@moltzap/client 2026.520.1 → 2026.520.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/start.d.ts +58 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +455 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/start.test.d.ts +2 -0
- package/dist/cli/commands/start.test.d.ts.map +1 -0
- package/dist/cli/commands/start.test.js +626 -0
- package/dist/cli/commands/start.test.js.map +1 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `moltzap start <name> <participant>... [--message <text>] [--app-id <uuid>]`
|
|
3
|
+
*
|
|
4
|
+
* Spec D2 (#599) — single-command CLI composition over Spec D1's atomic
|
|
5
|
+
* `TaskCreate({ appId, invitedAgentIds, initialConversation })` plus an
|
|
6
|
+
* optional `MessagesSend`. Today's two-step workflow
|
|
7
|
+
* (`conversations create` -> `send conv:<id> <text>`) collapses into
|
|
8
|
+
* one subcommand for the common case.
|
|
9
|
+
*
|
|
10
|
+
* See also:
|
|
11
|
+
* - `packages/protocol/src/task/tasks.ts -> TaskCreate` / `DEFAULT_APP_ID` /
|
|
12
|
+
* `AppId` — D1 (#598) wire surface this command composes.
|
|
13
|
+
* - `packages/client/docs/architecture/moltzap-start-cli.md` for the
|
|
14
|
+
* command flow diagram, exit-code contract, and test alignment.
|
|
15
|
+
* - `packages/client/src/cli/commands/conversations.ts -> createConversation`
|
|
16
|
+
* for the legacy two-step DM/Group create path D2 replaces. Untouched
|
|
17
|
+
* in D2; D3 (#600) deletes it.
|
|
18
|
+
* - `packages/client/src/cli/socket-client.ts -> resolveParticipant` —
|
|
19
|
+
* NOT reused by D2 because that helper goes via the daemon
|
|
20
|
+
* socket (`socket-client.ts -> request`), bypassing the CLI
|
|
21
|
+
* `Transport` service that `start.ts` uses for `TaskCreate` /
|
|
22
|
+
* `MessagesSend`. Mixing the two would make `--as`-mode name lookups
|
|
23
|
+
* hit the daemon (potentially absent) and would not be testable
|
|
24
|
+
* via `makeFakeTransport`. D2 introduces a local `resolveAgentTokens`
|
|
25
|
+
* helper that goes through `transport.ts -> rpc` instead
|
|
26
|
+
* (see per-flow doc §6 + §"Why we don't reuse `resolveParticipant`").
|
|
27
|
+
*/
|
|
28
|
+
import { Command } from "@effect/cli";
|
|
29
|
+
import { Effect, Option } from "effect";
|
|
30
|
+
import { type Transport } from "../transport.js";
|
|
31
|
+
/**
|
|
32
|
+
* Parsed CLI arguments for the `start` command. `@effect/cli`'s
|
|
33
|
+
* `Args.repeated` admits zero participants — caller-only tasks are
|
|
34
|
+
* permitted at the wire (Spec D1 per-flow doc 12) but not exercised by
|
|
35
|
+
* spec D2 ACs (which cover `length === 1` DM and `length >= 2` group
|
|
36
|
+
* shapes). Handler MUST NOT reject empty `participants`.
|
|
37
|
+
*/
|
|
38
|
+
export interface StartCommandArgs {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly participants: readonly string[];
|
|
41
|
+
readonly message: string | undefined;
|
|
42
|
+
readonly appId: string | undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Test seam: invoke the handler directly with parsed args, bypassing
|
|
46
|
+
* `@effect/cli`'s parser. Returns the same `Effect` the `Command.make`
|
|
47
|
+
* wrapper would produce, including the `runStartCommand` exit-code
|
|
48
|
+
* dispatcher. Tests `Effect.provideService(Transport, fake)` and assert
|
|
49
|
+
* `process.exit` was called with the expected code.
|
|
50
|
+
*/
|
|
51
|
+
export declare const runStartHandler: (args: StartCommandArgs) => Effect.Effect<void, never, Transport>;
|
|
52
|
+
export declare const startCommand: Command.Command<"start", Transport, never, {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly participants: string[];
|
|
55
|
+
readonly message: Option.Option<string>;
|
|
56
|
+
readonly appId: Option.Option<string>;
|
|
57
|
+
}>;
|
|
58
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAQ,OAAO,EAAW,MAAM,aAAa,CAAC;AACrD,OAAO,EAAQ,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAetD,OAAO,EAAO,KAAK,SAAS,EAAuB,MAAM,iBAAiB,CAAC;AA0E3E;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AA0iBD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CACK,CAAC;AAE7C,eAAO,MAAM,YAAY;;;;;EA8BxB,CAAC"}
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `moltzap start <name> <participant>... [--message <text>] [--app-id <uuid>]`
|
|
3
|
+
*
|
|
4
|
+
* Spec D2 (#599) — single-command CLI composition over Spec D1's atomic
|
|
5
|
+
* `TaskCreate({ appId, invitedAgentIds, initialConversation })` plus an
|
|
6
|
+
* optional `MessagesSend`. Today's two-step workflow
|
|
7
|
+
* (`conversations create` -> `send conv:<id> <text>`) collapses into
|
|
8
|
+
* one subcommand for the common case.
|
|
9
|
+
*
|
|
10
|
+
* See also:
|
|
11
|
+
* - `packages/protocol/src/task/tasks.ts -> TaskCreate` / `DEFAULT_APP_ID` /
|
|
12
|
+
* `AppId` — D1 (#598) wire surface this command composes.
|
|
13
|
+
* - `packages/client/docs/architecture/moltzap-start-cli.md` for the
|
|
14
|
+
* command flow diagram, exit-code contract, and test alignment.
|
|
15
|
+
* - `packages/client/src/cli/commands/conversations.ts -> createConversation`
|
|
16
|
+
* for the legacy two-step DM/Group create path D2 replaces. Untouched
|
|
17
|
+
* in D2; D3 (#600) deletes it.
|
|
18
|
+
* - `packages/client/src/cli/socket-client.ts -> resolveParticipant` —
|
|
19
|
+
* NOT reused by D2 because that helper goes via the daemon
|
|
20
|
+
* socket (`socket-client.ts -> request`), bypassing the CLI
|
|
21
|
+
* `Transport` service that `start.ts` uses for `TaskCreate` /
|
|
22
|
+
* `MessagesSend`. Mixing the two would make `--as`-mode name lookups
|
|
23
|
+
* hit the daemon (potentially absent) and would not be testable
|
|
24
|
+
* via `makeFakeTransport`. D2 introduces a local `resolveAgentTokens`
|
|
25
|
+
* helper that goes through `transport.ts -> rpc` instead
|
|
26
|
+
* (see per-flow doc §6 + §"Why we don't reuse `resolveParticipant`").
|
|
27
|
+
*/
|
|
28
|
+
import { Args, Command, Options } from "@effect/cli";
|
|
29
|
+
import { Data, Effect, Either, Option } from "effect";
|
|
30
|
+
import { AgentsLookupByName, DEFAULT_APP_ID, MessagesSend, TaskConversationList, TaskCreate, } from "@moltzap/protocol";
|
|
31
|
+
import { rpc } from "../transport.js";
|
|
32
|
+
// ─── Exit-code contract (spec D2 Goal 5 + Goal 7) ─────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Exit-code table for the `moltzap start` command. Values are documented
|
|
35
|
+
* in `Command.withDescription` help text below; the handler branches on
|
|
36
|
+
* these via `runStartCommand` and inline `process.exit` in the
|
|
37
|
+
* partial-success path.
|
|
38
|
+
*/
|
|
39
|
+
const EXIT_CODES = {
|
|
40
|
+
SUCCESS: 0,
|
|
41
|
+
TASK_CREATE_FAILED: 1,
|
|
42
|
+
PARTIAL_SUCCESS: 2,
|
|
43
|
+
USAGE_ERROR: 64,
|
|
44
|
+
};
|
|
45
|
+
// ─── Tagged errors (CLI-local) ────────────────────────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* `--app-id <value>` failed syntactic UUID v4 validation before any RPC.
|
|
48
|
+
* Maps to `EXIT_CODES.USAGE_ERROR`; stderr prints
|
|
49
|
+
* `Invalid --app-id: not a UUID`. Local to this module — tests assert
|
|
50
|
+
* by exit code + stderr text rather than `expect().toBeInstanceOf(...)`,
|
|
51
|
+
* so the class stays unexported per the architect plan.
|
|
52
|
+
*/
|
|
53
|
+
class InvalidAppIdError extends Data.TaggedError("InvalidAppIdError") {
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* An `agent:<name>` or `agent:<uuid>` participant token could not be
|
|
57
|
+
* resolved (name not in the agent roster, or token mis-shaped). Maps
|
|
58
|
+
* to `EXIT_CODES.USAGE_ERROR`; stderr names the unresolved token.
|
|
59
|
+
*
|
|
60
|
+
* Resolver calls `AgentsLookupByName` (a server RPC) for name-shaped
|
|
61
|
+
* tokens. That RPC is read-only and does not mutate server state, so
|
|
62
|
+
* the partial-failure invariant is unaffected. The spec D2 AC clause
|
|
63
|
+
* "NO RPC calls" reads as "NO mutating (TaskCreate / MessagesSend)
|
|
64
|
+
* calls" in this plan; see per-flow doc §8 + plan §R5.
|
|
65
|
+
*/
|
|
66
|
+
class UnresolvedParticipantError extends Data.TaggedError("UnresolvedParticipantError") {
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Too many DISTINCT name-shaped tokens to batch into one
|
|
70
|
+
* `AgentsLookupByName` RPC (schema caps `names` at `maxItems: 100`).
|
|
71
|
+
* Maps to `EXIT_CODES.USAGE_ERROR`; stderr names the offending count.
|
|
72
|
+
*
|
|
73
|
+
* Distinct from `UnresolvedParticipantError` — fires BEFORE any RPC, on
|
|
74
|
+
* a count check. Without this carve-out, 101+ unique names would
|
|
75
|
+
* trigger an opaque AJV decode failure mapped to exit 1 ("Failed:
|
|
76
|
+
* params decode error"); this surfaces it as a usage error instead.
|
|
77
|
+
*/
|
|
78
|
+
class TooManyParticipantNamesError extends Data.TaggedError("TooManyParticipantNamesError") {
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Cap pinned to `AgentsLookupByName.params.names: Type.Array(...,
|
|
82
|
+
* { maxItems: 100 })`. Drift here vs. the schema causes a confusing
|
|
83
|
+
* exit-1 AJV rejection instead of the exit-64 usage error.
|
|
84
|
+
*/
|
|
85
|
+
const MAX_NAME_LOOKUP_BATCH = 100;
|
|
86
|
+
// ─── UUID validation ──────────────────────────────────────────────────────
|
|
87
|
+
/**
|
|
88
|
+
* RFC 4122 UUID v4 regex per plan Invariant 7. The `4` in the third
|
|
89
|
+
* group pins the version; the `[89ab]` in the fourth group pins the
|
|
90
|
+
* variant. Pre-existing `socket-client.ts -> UUID_RE` accepts any UUID
|
|
91
|
+
* version, which would let v3/v5/v7 tokens through; spec D2 Goal 7
|
|
92
|
+
* requires v4-specific rejection at exit 64.
|
|
93
|
+
*/
|
|
94
|
+
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
95
|
+
const validateAppId = (value) => UUID_V4_RE.test(value)
|
|
96
|
+
? Effect.succeed(value)
|
|
97
|
+
: Effect.fail(new InvalidAppIdError({ value }));
|
|
98
|
+
// ─── Participant token resolver ───────────────────────────────────────────
|
|
99
|
+
const AGENT_TOKEN_PREFIX = "agent:";
|
|
100
|
+
const classifyToken = (token) => {
|
|
101
|
+
const failShape = Effect.fail(new UnresolvedParticipantError({ token, reason: "shape" }));
|
|
102
|
+
if (!token.startsWith(AGENT_TOKEN_PREFIX))
|
|
103
|
+
return failShape;
|
|
104
|
+
const rest = token.slice(AGENT_TOKEN_PREFIX.length);
|
|
105
|
+
if (rest.length === 0)
|
|
106
|
+
return failShape;
|
|
107
|
+
if (UUID_V4_RE.test(rest)) {
|
|
108
|
+
return Effect.succeed({ kind: "uuid", id: rest });
|
|
109
|
+
}
|
|
110
|
+
return Effect.succeed({ kind: "name", token, name: rest });
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Resolve all participant tokens to bare `AgentId`s matching
|
|
114
|
+
* `TaskCreate.params.invitedAgentIds: Array(AgentId)` directly (no
|
|
115
|
+
* `.map(p => p.id)` step needed).
|
|
116
|
+
*
|
|
117
|
+
* Failure modes (first in input order wins):
|
|
118
|
+
* - Token does not start with `agent:` (or is `agent:` with empty
|
|
119
|
+
* name) -> `UnresolvedParticipantError({ reason: "shape" })`.
|
|
120
|
+
* - Token is `agent:<name>` and the batched lookup returns no agent
|
|
121
|
+
* matching `name` -> `UnresolvedParticipantError({ reason:
|
|
122
|
+
* "not-found" })`.
|
|
123
|
+
*
|
|
124
|
+
* WHY one batched RPC instead of one-per-token: `AgentsLookupByName`
|
|
125
|
+
* accepts `names: Array(..., { minItems: 1, maxItems: 100 })`. Coalesce
|
|
126
|
+
* unique name-shaped tokens into a single RPC; UUID-shaped tokens skip
|
|
127
|
+
* the wire entirely. Resolution map keys on agent name so duplicate
|
|
128
|
+
* tokens (`agent:bob agent:bob`) resolve to the same id without
|
|
129
|
+
* re-asking the server.
|
|
130
|
+
*
|
|
131
|
+
* Architect plan §R1 explains why this is a local helper rather than
|
|
132
|
+
* reusing `socket-client.ts -> resolveParticipant` (transport mismatch,
|
|
133
|
+
* testability, wire-shape match).
|
|
134
|
+
*/
|
|
135
|
+
const uniqueNamesOf = (classified) => Array.from(new Set(classified.flatMap((c) => (c.kind === "name" ? [c.name] : []))));
|
|
136
|
+
/**
|
|
137
|
+
* Look up `names` in one batched RPC (no-op when empty) and return a
|
|
138
|
+
* name→AgentId map keyed by FIRST agent per name. The server's response
|
|
139
|
+
* is a flat agents array; mapping by name preserves the pre-P3-2
|
|
140
|
+
* tie-break ("first agent wins"). Caps at `MAX_NAME_LOOKUP_BATCH`
|
|
141
|
+
* BEFORE the RPC to keep the >100 case as a usage error rather than a
|
|
142
|
+
* decode failure.
|
|
143
|
+
*/
|
|
144
|
+
const lookupAgentIdsByName = (names) => Effect.gen(function* () {
|
|
145
|
+
const byName = new Map();
|
|
146
|
+
if (names.length === 0)
|
|
147
|
+
return byName;
|
|
148
|
+
if (names.length > MAX_NAME_LOOKUP_BATCH) {
|
|
149
|
+
return yield* Effect.fail(new TooManyParticipantNamesError({
|
|
150
|
+
count: names.length,
|
|
151
|
+
max: MAX_NAME_LOOKUP_BATCH,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
// Defensive copy: AgentsLookupByName.params.names resolves to
|
|
155
|
+
// mutable `string[]` (TypeBox's `Static<Array>`); pass a shallow
|
|
156
|
+
// clone so the caller's readonly contract isn't bypassed.
|
|
157
|
+
const result = yield* rpc(AgentsLookupByName, { names: [...names] });
|
|
158
|
+
for (const agent of result.agents) {
|
|
159
|
+
if (!byName.has(agent.name))
|
|
160
|
+
byName.set(agent.name, agent.id);
|
|
161
|
+
}
|
|
162
|
+
return byName;
|
|
163
|
+
});
|
|
164
|
+
const resolveAgentTokens = (tokens) => Effect.gen(function* () {
|
|
165
|
+
const classified = yield* Effect.all(tokens.map(classifyToken));
|
|
166
|
+
const agentIdByName = yield* lookupAgentIdsByName(uniqueNamesOf(classified));
|
|
167
|
+
// Single for-loop avoids a second `Effect.all` over pure post-batch
|
|
168
|
+
// resolution (N extra Effect cells); fail-fast on first miss preserves
|
|
169
|
+
// input-order error semantics.
|
|
170
|
+
const resolved = [];
|
|
171
|
+
for (const entry of classified) {
|
|
172
|
+
if (entry.kind === "uuid") {
|
|
173
|
+
resolved.push(entry.id);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const id = agentIdByName.get(entry.name);
|
|
177
|
+
if (id === undefined) {
|
|
178
|
+
return yield* Effect.fail(new UnresolvedParticipantError({
|
|
179
|
+
token: entry.token,
|
|
180
|
+
reason: "not-found",
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
resolved.push(id);
|
|
184
|
+
}
|
|
185
|
+
return resolved;
|
|
186
|
+
});
|
|
187
|
+
// ─── Handler stages ───────────────────────────────────────────────────────
|
|
188
|
+
const resolveAppId = (raw) => raw === undefined ? Effect.succeed(DEFAULT_APP_ID) : validateAppId(raw);
|
|
189
|
+
const printTaskCreated = (task, conversation) => Effect.sync(() => {
|
|
190
|
+
console.log(`Task started: ${task.id} (conversation: ${conversation.id})`);
|
|
191
|
+
});
|
|
192
|
+
const printTaskReused = (task, conversation) => Effect.sync(() => {
|
|
193
|
+
console.log(`Task started: ${task.id} (reusing existing conversation: ${conversation.id})`);
|
|
194
|
+
});
|
|
195
|
+
const printTaskAlreadyClosed = (taskId) => Effect.sync(() => {
|
|
196
|
+
// WHY this single message covers two distinct conditions:
|
|
197
|
+
// (a) the existing task has no non-archived conversation, OR
|
|
198
|
+
// (b) the dedup-lookup window (1000 rows) did not surface one.
|
|
199
|
+
// (b) is rare per the activity-desc server ordering; if a heavy
|
|
200
|
+
// user trips it on an active task, the spec D2 amendment N6
|
|
201
|
+
// diagnostic is intentionally conservative ("closed") rather than
|
|
202
|
+
// claiming false freshness. The follow-up `moltzap conversations
|
|
203
|
+
// list` invocation surfaces the real state.
|
|
204
|
+
console.error(`Task already exists but is closed: ${taskId}`);
|
|
205
|
+
});
|
|
206
|
+
const printMessageSent = (messageId) => Effect.sync(() => {
|
|
207
|
+
console.log(`Message sent: ${messageId}`);
|
|
208
|
+
});
|
|
209
|
+
const sendFirstMessage = (conversationId, text) => Effect.either(rpc(MessagesSend, {
|
|
210
|
+
conversationId,
|
|
211
|
+
parts: [{ type: "text", text }],
|
|
212
|
+
})).pipe(Effect.flatMap(Either.match({
|
|
213
|
+
onLeft: (err) => Effect.sync(() => {
|
|
214
|
+
console.error(`Error sending message: ${err.message}`);
|
|
215
|
+
process.exit(EXIT_CODES.PARTIAL_SUCCESS);
|
|
216
|
+
}),
|
|
217
|
+
onRight: (ok) => printMessageSent(ok.message.id),
|
|
218
|
+
})));
|
|
219
|
+
const createTaskAtomic = (appId, invitedAgentIds, name) => Effect.gen(function* () {
|
|
220
|
+
// Defensive copies: TaskCreate's params type expects mutable arrays
|
|
221
|
+
// (TypeBox's Static<Array> resolves to T[], not readonly T[]); pass
|
|
222
|
+
// shallow clones so the caller's readonly contract isn't bypassed.
|
|
223
|
+
//
|
|
224
|
+
// Spec D2 (#599) amendment N7 (zero-participant carve-out):
|
|
225
|
+
// `InitialConversationSchema.participants` is `Type.Optional(Type.Array(AgentId,
|
|
226
|
+
// { minItems: 1 }))` — an EMPTY array fails server AJV. The
|
|
227
|
+
// caller-only path (help text + plan §R4 + `start.test.ts →
|
|
228
|
+
// zeroParticipants`) MUST omit `participants` entirely; the server
|
|
229
|
+
// adds the caller to `conversation_participants` implicitly. See
|
|
230
|
+
// `packages/protocol/src/task/tasks.ts → InitialConversationSchema`.
|
|
231
|
+
const initialConversation = invitedAgentIds.length === 0
|
|
232
|
+
? { name }
|
|
233
|
+
: { name, participants: [...invitedAgentIds] };
|
|
234
|
+
const result = yield* rpc(TaskCreate, {
|
|
235
|
+
appId,
|
|
236
|
+
invitedAgentIds: [...invitedAgentIds],
|
|
237
|
+
initialConversation,
|
|
238
|
+
});
|
|
239
|
+
if (result.conversation === null) {
|
|
240
|
+
// Dedup hit (per `tasks.handlers.ts → maybeTaskCreateDedup`): the
|
|
241
|
+
// server matched an existing task by `{caller} ∪ invitedAgentIds`
|
|
242
|
+
// and returned it with `conversation: null`. Handler resolves a
|
|
243
|
+
// reusable conversation via `findReusableConversation` instead of
|
|
244
|
+
// failing.
|
|
245
|
+
return { kind: "dedup", task: result.task };
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
kind: "created",
|
|
249
|
+
task: result.task,
|
|
250
|
+
conversation: result.conversation,
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
// ─── Dedup-hit conversation lookup (spec D2 amendment N6) ─────────────────
|
|
254
|
+
/**
|
|
255
|
+
* Page size + safety cap on `TaskConversationList` follow-up calls. The
|
|
256
|
+
* dedup-hit conversation should appear in the first page for any
|
|
257
|
+
* recently-touched task (server orders by activity desc, see
|
|
258
|
+
* `packages/server/src/task/services/conversation/list-pagination.ts →
|
|
259
|
+
* queryConversationListRows`). The cap protects against pathological
|
|
260
|
+
* cases where the caller has a very long list and the target task is
|
|
261
|
+
* older than the window can see — in which case we surface the closed-
|
|
262
|
+
* task diagnostic rather than spin indefinitely.
|
|
263
|
+
*/
|
|
264
|
+
const DEDUP_LOOKUP_PAGE_SIZE = 100;
|
|
265
|
+
const DEDUP_LOOKUP_MAX_PAGES = 10;
|
|
266
|
+
/**
|
|
267
|
+
* P2-A (spec D2 amendment N6) — locate a reusable conversation under a
|
|
268
|
+
* dedup-hit task. Tie-break rule: "first match in server iteration
|
|
269
|
+
* order" — server sorts by activity desc, so this is equivalent to
|
|
270
|
+
* most-recently-active. WHY a small page-count cap: a freshly-touched
|
|
271
|
+
* dedup-hit task lives near the top of the activity-sorted list; the
|
|
272
|
+
* 1000-row ceiling protects against pathological lists where the
|
|
273
|
+
* target is older than the lookup window can see (the closed-task
|
|
274
|
+
* diagnostic is the correct fallback per spec D2 amendment N6).
|
|
275
|
+
*/
|
|
276
|
+
/**
|
|
277
|
+
* Filter rule for the dedup-hit lookup: (a) the item's `taskId` must
|
|
278
|
+
* match the existing task we are reusing (the list is caller-scoped
|
|
279
|
+
* across ALL of the caller's tasks, not task-scoped); (b) the
|
|
280
|
+
* conversation must be non-archived (server includes archived rows
|
|
281
|
+
* unfiltered per `TaskConversationList`'s contract — clients filter
|
|
282
|
+
* `archivedAt !== undefined` locally; archived strings are absent
|
|
283
|
+
* on the wire when the row is active, never `null`, per
|
|
284
|
+
* `ConversationSchema.archivedAt: Type.Optional(DateTimeString)`).
|
|
285
|
+
*/
|
|
286
|
+
const pickReusableFromPage = (items, taskId) => {
|
|
287
|
+
const match = items.find((item) => item.taskId === taskId && item.conversation.archivedAt === undefined);
|
|
288
|
+
return match === undefined ? null : match.conversation;
|
|
289
|
+
};
|
|
290
|
+
const findReusableConversation = (taskId) => Effect.gen(function* () {
|
|
291
|
+
let cursor = undefined;
|
|
292
|
+
for (let page = 0; page < DEDUP_LOOKUP_MAX_PAGES; page++) {
|
|
293
|
+
const params = {
|
|
294
|
+
limit: DEDUP_LOOKUP_PAGE_SIZE,
|
|
295
|
+
};
|
|
296
|
+
if (cursor !== undefined)
|
|
297
|
+
params.cursor = cursor;
|
|
298
|
+
const result = yield* rpc(TaskConversationList, params);
|
|
299
|
+
const hit = pickReusableFromPage(result.items, taskId);
|
|
300
|
+
if (hit !== null)
|
|
301
|
+
return hit;
|
|
302
|
+
if (result.nextCursor === undefined)
|
|
303
|
+
return null;
|
|
304
|
+
cursor = result.nextCursor;
|
|
305
|
+
}
|
|
306
|
+
return null;
|
|
307
|
+
});
|
|
308
|
+
/**
|
|
309
|
+
* Spec D2 amendment N6 — dedup-hit branch. `TaskConversationList`
|
|
310
|
+
* wire failures are captured inline via `Effect.either` (same pattern
|
|
311
|
+
* + same reason as `sendFirstMessage`'s partial-success handling)
|
|
312
|
+
* because `TaskCreate` already succeeded server-side; routing the
|
|
313
|
+
* list error through `runStartCommand`'s `catchAll` would print
|
|
314
|
+
* `Failed: <list-error>`, misleading the user into thinking the
|
|
315
|
+
* create failed.
|
|
316
|
+
*/
|
|
317
|
+
const onReuseFound = (task, reuse, message) => Effect.zipRight(printTaskReused(task, reuse), Option.match(message, {
|
|
318
|
+
onNone: () => Effect.void,
|
|
319
|
+
onSome: (m) => sendFirstMessage(reuse.id, m),
|
|
320
|
+
}));
|
|
321
|
+
const onReuseNull = (task) => Effect.zipRight(printTaskAlreadyClosed(task.id), Effect.sync(() => {
|
|
322
|
+
process.exit(EXIT_CODES.TASK_CREATE_FAILED);
|
|
323
|
+
}));
|
|
324
|
+
const handleDedupOutcome = (task, message) => Effect.either(findReusableConversation(task.id)).pipe(Effect.flatMap(Either.match({
|
|
325
|
+
onLeft: (err) => Effect.sync(() => {
|
|
326
|
+
console.error(`Task ${task.id} already exists but reusable-conversation lookup failed: ${err.message}`);
|
|
327
|
+
process.exit(EXIT_CODES.TASK_CREATE_FAILED);
|
|
328
|
+
}),
|
|
329
|
+
onRight: (reuse) => reuse === null
|
|
330
|
+
? onReuseNull(task)
|
|
331
|
+
: onReuseFound(task, reuse, message),
|
|
332
|
+
})));
|
|
333
|
+
// ─── Handler body ─────────────────────────────────────────────────────────
|
|
334
|
+
/**
|
|
335
|
+
* `moltzap start` handler. Four stages (see per-flow doc 09 §6):
|
|
336
|
+
*
|
|
337
|
+
* 1. Validate `args.appId` UUID v4 if set; else use `DEFAULT_APP_ID`.
|
|
338
|
+
* Failure -> `InvalidAppIdError` -> exit 64 via `runStartCommand`.
|
|
339
|
+
* 2. Resolve `args.participants` via `resolveAgentTokens` (single
|
|
340
|
+
* batched `AgentsLookupByName` RPC for name-shaped tokens;
|
|
341
|
+
* UUID-shaped tokens short-circuit). Any token failure ->
|
|
342
|
+
* `UnresolvedParticipantError` -> exit 64.
|
|
343
|
+
* 3. `rpc(TaskCreate, { appId, invitedAgentIds, initialConversation })`
|
|
344
|
+
* where `initialConversation` carries `participants` ONLY when
|
|
345
|
+
* `invitedAgentIds.length > 0` (P2-B). Two success outcomes:
|
|
346
|
+
* - `created`: server returned a fresh `conversation`. Print
|
|
347
|
+
* `Task started: <taskId> (conversation: <convId>)`.
|
|
348
|
+
* - `dedup`: server returned `conversation: null` because
|
|
349
|
+
* `{caller} ∪ invitedAgentIds` already owned a task on this
|
|
350
|
+
* appId (P2-A). Auto-fetch the most-recently-active non-
|
|
351
|
+
* archived conversation under the existing task via
|
|
352
|
+
* `findReusableConversation` and print
|
|
353
|
+
* `Task started: <taskId> (reusing existing conversation: <convId>)`.
|
|
354
|
+
* If no usable conversation exists (closed task, all archived,
|
|
355
|
+
* or out of dedup-lookup window), print
|
|
356
|
+
* `Task already exists but is closed: <taskId>` to stderr and
|
|
357
|
+
* exit 1.
|
|
358
|
+
* `TaskCreate` wire failure -> `TransportError` -> exit 1 via
|
|
359
|
+
* `runStartCommand`, no stdout.
|
|
360
|
+
* 4. If `args.message` is set AND a conversation was produced (either
|
|
361
|
+
* kind), call `rpc(MessagesSend, { conversationId, parts: [{ type:
|
|
362
|
+
* "text", text }] })` wrapped in `Effect.either`. Success -> print
|
|
363
|
+
* `Message sent: <msgId>`, exit 0. Failure -> print
|
|
364
|
+
* `Error sending message: <err>` to stderr, exit 2 via inline
|
|
365
|
+
* `process.exit` (preserves the already-printed stdout line;
|
|
366
|
+
* cannot route through `runStartCommand`).
|
|
367
|
+
*/
|
|
368
|
+
const startCommandHandler = (args) => Effect.gen(function* () {
|
|
369
|
+
const appId = yield* resolveAppId(args.appId);
|
|
370
|
+
const invitedAgentIds = yield* resolveAgentTokens(args.participants);
|
|
371
|
+
const outcome = yield* createTaskAtomic(appId, invitedAgentIds, args.name);
|
|
372
|
+
const messageOpt = Option.fromNullable(args.message);
|
|
373
|
+
if (outcome.kind === "dedup") {
|
|
374
|
+
yield* handleDedupOutcome(outcome.task, messageOpt);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
yield* printTaskCreated(outcome.task, outcome.conversation);
|
|
378
|
+
yield* Option.match(messageOpt, {
|
|
379
|
+
onNone: () => Effect.void,
|
|
380
|
+
onSome: (m) => sendFirstMessage(outcome.conversation.id, m),
|
|
381
|
+
});
|
|
382
|
+
}).pipe(Effect.withSpan("startCommandHandler"));
|
|
383
|
+
// ─── Exit-code dispatcher ─────────────────────────────────────────────────
|
|
384
|
+
/**
|
|
385
|
+
* Outer adapter that replaces the shared `transport.ts -> runHandler`
|
|
386
|
+
* (which collapses every error to exit 1) with a `_tag`-aware mapping
|
|
387
|
+
* per the spec D2 exit-code contract:
|
|
388
|
+
*
|
|
389
|
+
* `InvalidAppIdError` -> 64 + stderr `Invalid --app-id: not a UUID`
|
|
390
|
+
* `UnresolvedParticipantError` -> 64 + stderr `Cannot resolve "<token>": <reason>`
|
|
391
|
+
* `TooManyParticipantNamesError` -> 64 + stderr `Too many distinct agent names: <count> (max <max>)`
|
|
392
|
+
* any other `StartCommandError` -> 1 + stderr `Failed: <err.message>`
|
|
393
|
+
*
|
|
394
|
+
* The exit-2 partial-success branch runs inline inside
|
|
395
|
+
* `startCommandHandler` (after `Task started:` has been printed to
|
|
396
|
+
* stdout) and never reaches this adapter — re-throwing the post-
|
|
397
|
+
* `TaskCreate` error here would discard the already-printed stdout
|
|
398
|
+
* line.
|
|
399
|
+
*/
|
|
400
|
+
const runStartCommand = (effect) => effect.pipe(Effect.catchTag("InvalidAppIdError", () => Effect.sync(() => {
|
|
401
|
+
console.error("Invalid --app-id: not a UUID");
|
|
402
|
+
process.exit(EXIT_CODES.USAGE_ERROR);
|
|
403
|
+
})), Effect.catchTag("UnresolvedParticipantError", (err) => Effect.sync(() => {
|
|
404
|
+
console.error(`Cannot resolve "${err.token}": ${err.reason}`);
|
|
405
|
+
process.exit(EXIT_CODES.USAGE_ERROR);
|
|
406
|
+
})), Effect.catchTag("TooManyParticipantNamesError", (err) => Effect.sync(() => {
|
|
407
|
+
console.error(`Too many distinct agent names: ${err.count} (max ${err.max})`);
|
|
408
|
+
process.exit(EXIT_CODES.USAGE_ERROR);
|
|
409
|
+
})), Effect.catchAll((err) => Effect.sync(() => {
|
|
410
|
+
// `Data.TaggedError` populates `message` for every tagged-error
|
|
411
|
+
// subclass; `|| err._tag` is a belt-and-suspenders fallback for
|
|
412
|
+
// the (impossible-per-Data-contract) empty-message case.
|
|
413
|
+
const msg = err.message || err._tag;
|
|
414
|
+
console.error(`Failed: ${msg}`);
|
|
415
|
+
process.exit(EXIT_CODES.TASK_CREATE_FAILED);
|
|
416
|
+
})));
|
|
417
|
+
// ─── @effect/cli wiring ───────────────────────────────────────────────────
|
|
418
|
+
const nameArg = Args.text({ name: "name" }).pipe(Args.withDescription("Conversation name"));
|
|
419
|
+
const participantsArg = Args.text({ name: "participant" }).pipe(Args.withDescription("Participant token (e.g. agent:bob or agent:<uuid>). " +
|
|
420
|
+
"Zero or more allowed; D2 ACs cover 1 (DM-shape) and >=2 (group-shape)."), Args.repeated);
|
|
421
|
+
const messageOption = Options.text("message").pipe(Options.withDescription("First message body. If supplied, MessagesSend runs after the atomic " +
|
|
422
|
+
"TaskCreate (separate RPC, not server-atomic)."), Options.optional);
|
|
423
|
+
const appIdOption = Options.text("app-id").pipe(Options.withDescription("App UUID v4. Defaults to DEFAULT_APP_ID (D1 #635). Invalid syntax " +
|
|
424
|
+
"exits 64 with NO RPC calls (Goal 7)."), Options.optional);
|
|
425
|
+
/**
|
|
426
|
+
* Test seam: invoke the handler directly with parsed args, bypassing
|
|
427
|
+
* `@effect/cli`'s parser. Returns the same `Effect` the `Command.make`
|
|
428
|
+
* wrapper would produce, including the `runStartCommand` exit-code
|
|
429
|
+
* dispatcher. Tests `Effect.provideService(Transport, fake)` and assert
|
|
430
|
+
* `process.exit` was called with the expected code.
|
|
431
|
+
*/
|
|
432
|
+
export const runStartHandler = (args) => runStartCommand(startCommandHandler(args));
|
|
433
|
+
export const startCommand = Command.make("start", {
|
|
434
|
+
name: nameArg,
|
|
435
|
+
participants: participantsArg,
|
|
436
|
+
message: messageOption,
|
|
437
|
+
appId: appIdOption,
|
|
438
|
+
}, ({ name, participants, message, appId }) => runStartHandler({
|
|
439
|
+
name,
|
|
440
|
+
participants,
|
|
441
|
+
message: Option.getOrUndefined(message),
|
|
442
|
+
appId: Option.getOrUndefined(appId),
|
|
443
|
+
})).pipe(Command.withDescription("Start a task with named participants and (optionally) send the " +
|
|
444
|
+
"first message in one atomic step. Spec D2 #599 — composes Spec D1 " +
|
|
445
|
+
"TaskCreate + MessagesSend.\n" +
|
|
446
|
+
"\n" +
|
|
447
|
+
"Zero participants creates a caller-only task (rare; usually you " +
|
|
448
|
+
"will pass one or more `agent:<name>` tokens).\n" +
|
|
449
|
+
"\n" +
|
|
450
|
+
"Exit codes:\n" +
|
|
451
|
+
` ${EXIT_CODES.SUCCESS} success (TaskCreate + optional MessagesSend resolved)\n` +
|
|
452
|
+
` ${EXIT_CODES.TASK_CREATE_FAILED} TaskCreate failed (stdout empty)\n` +
|
|
453
|
+
` ${EXIT_CODES.PARTIAL_SUCCESS} TaskCreate OK, MessagesSend failed (no rollback)\n` +
|
|
454
|
+
` ${EXIT_CODES.USAGE_ERROR} usage error (bad --app-id UUID, unresolvable agent token, or >${MAX_NAME_LOOKUP_BATCH} distinct name-shaped tokens)`));
|
|
455
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,UAAU,GAOX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAuC,MAAM,iBAAiB,CAAC;AAE3E,6EAA6E;AAE7E;;;;;GAKG;AACH,MAAM,UAAU,GAAG;IACjB,OAAO,EAAE,CAAC;IACV,kBAAkB,EAAE,CAAC;IACrB,eAAe,EAAE,CAAC;IAClB,WAAW,EAAE,EAAE;CACP,CAAC;AAEX,6EAA6E;AAE7E;;;;;;GAMG;AACH,MAAM,iBAAkB,SAAQ,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAElE;CAAG;AAEL;;;;;;;;;;GAUG;AACH,MAAM,0BAA2B,SAAQ,IAAI,CAAC,WAAW,CACvD,4BAA4B,CAI5B;CAAG;AAEL;;;;;;;;;GASG;AACH,MAAM,4BAA6B,SAAQ,IAAI,CAAC,WAAW,CACzD,8BAA8B,CAI9B;CAAG;AAEL;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,GAAG,CAAC;AA0ClC,6EAA6E;AAE7E;;;;;;GAMG;AACH,MAAM,UAAU,GACd,wEAAwE,CAAC;AAE3E,MAAM,aAAa,GAAG,CACpB,KAAa,EAC4B,EAAE,CAC3C,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAc,CAAC;IAChC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAEpD,6EAA6E;AAE7E,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAWpC,MAAM,aAAa,GAAG,CACpB,KAAa,EAC0C,EAAE;IACzD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAC3B,IAAI,0BAA0B,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAC3D,CAAC;IACF,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAe,EAAW,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAW,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,aAAa,GAAG,CAAC,UAAiC,EAAqB,EAAE,CAC7E,KAAK,CAAC,IAAI,CACR,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACxE,CAAC;AAEJ;;;;;;;GAOG;AACH,MAAM,oBAAoB,GAAG,CAC3B,KAAwB,EAKxB,EAAE,CACF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,4BAA4B,CAAC;YAC/B,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,GAAG,EAAE,qBAAqB;SAC3B,CAAC,CACH,CAAC;IACJ,CAAC;IACD,8DAA8D;IAC9D,iEAAiE;IACjE,0DAA0D;IAC1D,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IACrE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEL,MAAM,kBAAkB,GAAG,CACzB,MAAyB,EAKzB,EAAE,CACF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,oBAAoB,CAC/C,aAAa,CAAC,UAAU,CAAC,CAC1B,CAAC;IACF,oEAAoE;IACpE,uEAAuE;IACvE,+BAA+B;IAC/B,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,0BAA0B,CAAC;gBAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,WAAW;aACpB,CAAC,CACH,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,6EAA6E;AAE7E,MAAM,YAAY,GAAG,CACnB,GAAuB,EACkB,EAAE,CAC3C,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAE1E,MAAM,gBAAgB,GAAG,CACvB,IAAU,EACV,YAA0B,EACL,EAAE,CACvB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,EAAE,mBAAmB,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEL,MAAM,eAAe,GAAG,CACtB,IAAU,EACV,YAA0B,EACL,EAAE,CACvB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,GAAG,CACT,iBAAiB,IAAI,CAAC,EAAE,oCAAoC,YAAY,CAAC,EAAE,GAAG,CAC/E,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL,MAAM,sBAAsB,GAAG,CAAC,MAAc,EAAuB,EAAE,CACrE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,0DAA0D;IAC1D,6DAA6D;IAC7D,+DAA+D;IAC/D,gEAAgE;IAChE,4DAA4D;IAC5D,kEAAkE;IAClE,iEAAiE;IACjE,4CAA4C;IAC5C,OAAO,CAAC,KAAK,CAAC,sCAAsC,MAAM,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC;AAEL,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAuB,EAAE,CAClE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,GAAG,CAAC,iBAAiB,SAAS,EAAE,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEL,MAAM,gBAAgB,GAAG,CACvB,cAA8B,EAC9B,IAAY,EAC2B,EAAE,CACzC,MAAM,CAAC,MAAM,CACX,GAAG,CAAC,YAAY,EAAE;IAChB,cAAc;IACd,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;CAChC,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,OAAO,CACZ,MAAM,CAAC,KAAK,CAAC;IACX,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CACd,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAC3C,CAAC,CAAC;IACJ,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACjD,CAAC,CACH,CACF,CAAC;AAqBJ,MAAM,gBAAgB,GAAG,CACvB,KAAY,EACZ,eAAmC,EACnC,IAAY,EACiD,EAAE,CAC/D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,oEAAoE;IACpE,oEAAoE;IACpE,mEAAmE;IACnE,EAAE;IACF,4DAA4D;IAC5D,iFAAiF;IACjF,4DAA4D;IAC5D,4DAA4D;IAC5D,mEAAmE;IACnE,iEAAiE;IACjE,qEAAqE;IACrE,MAAM,mBAAmB,GACvB,eAAe,CAAC,MAAM,KAAK,CAAC;QAC1B,CAAC,CAAC,EAAE,IAAI,EAAE;QACV,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,GAAG,eAAe,CAAC,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE;QACpC,KAAK;QACL,eAAe,EAAE,CAAC,GAAG,eAAe,CAAC;QACrC,mBAAmB;KACpB,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QACjC,kEAAkE;QAClE,kEAAkE;QAClE,gEAAgE;QAChE,kEAAkE;QAClE,WAAW;QACX,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAW,CAAC;IACvD,CAAC;IACD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC,YAAY;KACzB,CAAC;AACb,CAAC,CAAC,CAAC;AAEL,6EAA6E;AAE7E;;;;;;;;;GASG;AACH,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AACH,MAAM,oBAAoB,GAAG,CAC3B,KAA8C,EAC9C,MAAc,EACO,EAAE;IACvB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CACtB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,KAAK,SAAS,CACvE,CAAC;IACF,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAC/B,MAAc,EACiD,EAAE,CACjE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,MAAM,GAAuB,SAAS,CAAC;IAC3C,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,sBAAsB,EAAE,IAAI,EAAE,EAAE,CAAC;QACzD,MAAM,MAAM,GAAuC;YACjD,KAAK,EAAE,sBAAsB;SAC9B,CAAC;QACF,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACjD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC;QAC7B,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACjD,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEL;;;;;;;;GAQG;AACH,MAAM,YAAY,GAAG,CACnB,IAAU,EACV,KAAmB,EACnB,OAA8B,EACS,EAAE,CACzC,MAAM,CAAC,QAAQ,CACb,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,EAC5B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;IACpB,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;IACzB,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;CAC7C,CAAC,CACH,CAAC;AAEJ,MAAM,WAAW,GAAG,CAAC,IAAU,EAAyC,EAAE,CACxE,MAAM,CAAC,QAAQ,CACb,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,EAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAC9C,CAAC,CAAC,CACH,CAAC;AAEJ,MAAM,kBAAkB,GAAG,CACzB,IAAU,EACV,OAA8B,EACS,EAAE,CACzC,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CACnD,MAAM,CAAC,OAAO,CACZ,MAAM,CAAC,KAAK,CAAC;IACX,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CACd,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,OAAO,CAAC,KAAK,CACX,QAAQ,IAAI,CAAC,EAAE,4DAA4D,GAAG,CAAC,OAAO,EAAE,CACzF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC,CAAC;IACJ,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK,KAAK,IAAI;QACZ,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC;QACnB,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC;CACzC,CAAC,CACH,CACF,CAAC;AAEJ,6EAA6E;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,mBAAmB,GAAG,CAC1B,IAAsB,EAC6B,EAAE,CACrD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5D,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE;QAC9B,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;QACzB,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;KAC5D,CAAC,CAAC;AACL,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAElD,6EAA6E;AAE7E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,eAAe,GAAG,CACtB,MAAyD,EAClB,EAAE,CACzC,MAAM,CAAC,IAAI,CACT,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE,CACxC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC,CAAC,CACH,EACD,MAAM,CAAC,QAAQ,CAAC,4BAA4B,EAAE,CAAC,GAAG,EAAE,EAAE,CACpD,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC,CAAC,CACH,EACD,MAAM,CAAC,QAAQ,CAAC,8BAA8B,EAAE,CAAC,GAAG,EAAE,EAAE,CACtD,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,KAAK,CACX,kCAAkC,GAAG,CAAC,KAAK,SAAS,GAAG,CAAC,GAAG,GAAG,CAC/D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC,CAAC,CACH,EACD,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,gEAAgE;IAChE,gEAAgE;IAChE,yDAAyD;IACzD,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAC9C,CAAC,CAAC,CACH,CACF,CAAC;AAEJ,6EAA6E;AAE7E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAC9C,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAC1C,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,IAAI,CAC7D,IAAI,CAAC,eAAe,CAClB,sDAAsD;IACpD,wEAAwE,CAC3E,EACD,IAAI,CAAC,QAAQ,CACd,CAAC;AAEF,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAChD,OAAO,CAAC,eAAe,CACrB,sEAAsE;IACpE,+CAA+C,CAClD,EACD,OAAO,CAAC,QAAQ,CACjB,CAAC;AAEF,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC7C,OAAO,CAAC,eAAe,CACrB,oEAAoE;IAClE,sCAAsC,CACzC,EACD,OAAO,CAAC,QAAQ,CACjB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,IAAsB,EACiB,EAAE,CACzC,eAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CACtC,OAAO,EACP;IACE,IAAI,EAAE,OAAO;IACb,YAAY,EAAE,eAAe;IAC7B,OAAO,EAAE,aAAa;IACtB,KAAK,EAAE,WAAW;CACnB,EACD,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CACzC,eAAe,CAAC;IACd,IAAI;IACJ,YAAY;IACZ,OAAO,EAAE,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC;CACpC,CAAC,CACL,CAAC,IAAI,CACJ,OAAO,CAAC,eAAe,CACrB,iEAAiE;IAC/D,oEAAoE;IACpE,8BAA8B;IAC9B,IAAI;IACJ,kEAAkE;IAClE,iDAAiD;IACjD,IAAI;IACJ,eAAe;IACf,KAAK,UAAU,CAAC,OAAO,4DAA4D;IACnF,KAAK,UAAU,CAAC,kBAAkB,uCAAuC;IACzE,KAAK,UAAU,CAAC,eAAe,uDAAuD;IACtF,KAAK,UAAU,CAAC,WAAW,mEAAmE,qBAAqB,+BAA+B,CACrJ,CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for `moltzap start` (spec D2 #599 / sub-issue #661).
|
|
3
|
+
*
|
|
4
|
+
* Coverage map matches per-flow doc 09 §7. Each test body is a named
|
|
5
|
+
* helper to keep describe-blocks under the 50-line per-function limit
|
|
6
|
+
* (matches the pattern in `transport.test.ts`).
|
|
7
|
+
*/
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
import * as fc from "fast-check";
|
|
10
|
+
import { it as effectIt } from "@effect/vitest";
|
|
11
|
+
import { afterEach, beforeEach, describe, expect, it as plainIt, vi, } from "vitest";
|
|
12
|
+
import { AgentsLookupByName, DEFAULT_APP_ID, MessagesSend, TaskConversationList, TaskCreate, } from "@moltzap/protocol";
|
|
13
|
+
import { Transport } from "../transport.js";
|
|
14
|
+
import { makeFakeTransport } from "./test-transport.js";
|
|
15
|
+
import { runStartHandler, startCommand } from "./start.js";
|
|
16
|
+
const it = effectIt.effect;
|
|
17
|
+
// ─── Contractual literals (also asserted in `help` test) ──────────────────
|
|
18
|
+
const HELP_SYNOPSIS = "Start a task with named participants";
|
|
19
|
+
const HELP_MENTIONS_MESSAGES_SEND = "MessagesSend";
|
|
20
|
+
const HELP_APP_ID_FLAG = "--app-id";
|
|
21
|
+
const HELP_EXIT_CODES_HEADING = "Exit codes:";
|
|
22
|
+
// ─── Fixtures ─────────────────────────────────────────────────────────────
|
|
23
|
+
const CONVERSATION_NAME = "demo";
|
|
24
|
+
const TASK_ID = "00000000-0000-4000-8000-000000000001";
|
|
25
|
+
const CONVERSATION_ID = "00000000-0000-4000-8000-00000000000c";
|
|
26
|
+
const MESSAGE_ID = "00000000-0000-4000-8000-00000000000a";
|
|
27
|
+
const INITIATOR_ID = "00000000-0000-4000-8000-0000000000f0";
|
|
28
|
+
const BOB_AGENT_ID = "00000000-0000-4000-8000-000000000ab1";
|
|
29
|
+
const CAROL_AGENT_ID = "00000000-0000-4000-8000-000000000ab2";
|
|
30
|
+
const DAVE_AGENT_ID_UUID = "00000000-0000-4000-8000-000000000ab3";
|
|
31
|
+
const NOW_ISO = "2026-05-19T00:00:00Z";
|
|
32
|
+
const VALID_APP_ID_OVERRIDE = "11111111-2222-4333-8444-555555555555";
|
|
33
|
+
const UUID_V1_OVERRIDE = "11111111-2222-1333-8444-555555555555";
|
|
34
|
+
const taskFixture = {
|
|
35
|
+
id: TASK_ID,
|
|
36
|
+
appId: DEFAULT_APP_ID,
|
|
37
|
+
initiatorAgentId: INITIATOR_ID,
|
|
38
|
+
status: "active",
|
|
39
|
+
tmEndpointAddress: "endpoint",
|
|
40
|
+
startedAt: NOW_ISO,
|
|
41
|
+
endedAt: null,
|
|
42
|
+
createdAt: NOW_ISO,
|
|
43
|
+
};
|
|
44
|
+
const conversationFixture = {
|
|
45
|
+
id: CONVERSATION_ID,
|
|
46
|
+
type: "group",
|
|
47
|
+
name: CONVERSATION_NAME,
|
|
48
|
+
createdBy: INITIATOR_ID,
|
|
49
|
+
createdAt: NOW_ISO,
|
|
50
|
+
updatedAt: NOW_ISO,
|
|
51
|
+
};
|
|
52
|
+
const messageFixture = {
|
|
53
|
+
id: MESSAGE_ID,
|
|
54
|
+
conversationId: CONVERSATION_ID,
|
|
55
|
+
senderId: INITIATOR_ID,
|
|
56
|
+
parts: [{ type: "text", text: "hello" }],
|
|
57
|
+
createdAt: NOW_ISO,
|
|
58
|
+
};
|
|
59
|
+
const agentCard = (id, name) => ({
|
|
60
|
+
id,
|
|
61
|
+
name,
|
|
62
|
+
status: "active",
|
|
63
|
+
});
|
|
64
|
+
const TASK_CREATE_OK = () => ({
|
|
65
|
+
task: taskFixture,
|
|
66
|
+
conversation: conversationFixture,
|
|
67
|
+
});
|
|
68
|
+
const MESSAGES_SEND_OK = () => ({ message: messageFixture });
|
|
69
|
+
const respondLookup = (call, config) => {
|
|
70
|
+
// Batched lookup (P3-2): coalesce all requested-name agent cards from
|
|
71
|
+
// the mock's `lookupResults` map. Names with no entry return nothing
|
|
72
|
+
// — the handler maps that to `UnresolvedParticipantError` per token.
|
|
73
|
+
const params = call.params;
|
|
74
|
+
const lookupResults = config.lookupResults ?? {};
|
|
75
|
+
const agents = params.names.flatMap((name) => lookupResults[name] ?? []);
|
|
76
|
+
return { agents };
|
|
77
|
+
};
|
|
78
|
+
const respondFromConfig = (config) => (call) => {
|
|
79
|
+
if (call.method === AgentsLookupByName.name) {
|
|
80
|
+
return respondLookup(call, config);
|
|
81
|
+
}
|
|
82
|
+
if (call.method === TaskCreate.name) {
|
|
83
|
+
return (config.taskCreate ?? TASK_CREATE_OK)();
|
|
84
|
+
}
|
|
85
|
+
if (call.method === MessagesSend.name) {
|
|
86
|
+
return (config.messagesSend ?? MESSAGES_SEND_OK)();
|
|
87
|
+
}
|
|
88
|
+
if (call.method === TaskConversationList.name) {
|
|
89
|
+
return (config.taskConversationList ?? (() => ({ items: [] })))(call);
|
|
90
|
+
}
|
|
91
|
+
return new Error(`Unexpected RPC: ${call.method}`);
|
|
92
|
+
};
|
|
93
|
+
const makeTransportWith = (config) => makeFakeTransport(respondFromConfig(config));
|
|
94
|
+
const runWith = (transport, args) => runStartHandler(args).pipe(Effect.provideService(Transport, transport));
|
|
95
|
+
const findCallOf = (calls, method) => calls.find((c) => c.method === method);
|
|
96
|
+
const taskCreateParams = (calls) => findCallOf(calls, TaskCreate.name).params;
|
|
97
|
+
const mutatingCalls = (calls) => calls.filter((c) => c.method === TaskCreate.name || c.method === MessagesSend.name);
|
|
98
|
+
const standardArgs = (participants, overrides = {}) => ({
|
|
99
|
+
name: CONVERSATION_NAME,
|
|
100
|
+
participants,
|
|
101
|
+
message: undefined,
|
|
102
|
+
appId: undefined,
|
|
103
|
+
...overrides,
|
|
104
|
+
});
|
|
105
|
+
const onlyBobLookup = () => ({
|
|
106
|
+
lookupResults: { bob: [agentCard(BOB_AGENT_ID, "bob")] },
|
|
107
|
+
});
|
|
108
|
+
const bobCarolLookup = () => ({
|
|
109
|
+
lookupResults: {
|
|
110
|
+
bob: [agentCard(BOB_AGENT_ID, "bob")],
|
|
111
|
+
carol: [agentCard(CAROL_AGENT_ID, "carol")],
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
// ─── Shared harness (console + process.exit) ──────────────────────────────
|
|
115
|
+
let stdoutSpy;
|
|
116
|
+
let stderrSpy;
|
|
117
|
+
let exitSpy;
|
|
118
|
+
const originalExit = process.exit;
|
|
119
|
+
const installHarness = () => {
|
|
120
|
+
stdoutSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
121
|
+
stderrSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
122
|
+
exitSpy = vi.fn();
|
|
123
|
+
process.exit = exitSpy;
|
|
124
|
+
};
|
|
125
|
+
const restoreHarness = () => {
|
|
126
|
+
process.exit = originalExit;
|
|
127
|
+
stdoutSpy.mockRestore();
|
|
128
|
+
stderrSpy.mockRestore();
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Single-source the install/restore lifecycle for one `body` execution.
|
|
132
|
+
* Used by property-test iterators (`expectNonV4Rejected`,
|
|
133
|
+
* `expectNonAgentTokenRejected`) so each `fc.assert` iteration gets a
|
|
134
|
+
* fresh, isolated harness without inline `installHarness()` / explicit
|
|
135
|
+
* `restoreHarness()` calls that drift out of sync over time. `finally`
|
|
136
|
+
* guarantees restore even on `expect` throw.
|
|
137
|
+
*/
|
|
138
|
+
const withInstalledHarness = (body) => {
|
|
139
|
+
installHarness();
|
|
140
|
+
try {
|
|
141
|
+
body();
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
restoreHarness();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const stderrLines = () => stderrSpy.mock.calls.map((c) => String(c[0] ?? ""));
|
|
148
|
+
// ─── Test bodies: participant model ───────────────────────────────────────
|
|
149
|
+
const dmShape = () => Effect.gen(function* () {
|
|
150
|
+
const { calls, transport } = makeTransportWith(onlyBobLookup());
|
|
151
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
152
|
+
const params = taskCreateParams(calls);
|
|
153
|
+
expect(params.invitedAgentIds).toEqual([BOB_AGENT_ID]);
|
|
154
|
+
expect(params.invitedAgentIds.length).toBe(1);
|
|
155
|
+
expect(params.initialConversation.participants).toEqual([BOB_AGENT_ID]);
|
|
156
|
+
expect(params.initialConversation.name).toBe(CONVERSATION_NAME);
|
|
157
|
+
});
|
|
158
|
+
const groupShape = () => Effect.gen(function* () {
|
|
159
|
+
const { calls, transport } = makeTransportWith(bobCarolLookup());
|
|
160
|
+
yield* runWith(transport, standardArgs(["agent:bob", "agent:carol"]));
|
|
161
|
+
const params = taskCreateParams(calls);
|
|
162
|
+
expect(params.invitedAgentIds).toEqual([BOB_AGENT_ID, CAROL_AGENT_ID]);
|
|
163
|
+
// Pins the P3-2 batched-lookup optimization: N name-shaped tokens
|
|
164
|
+
// coalesce into ONE `AgentsLookupByName` RPC, not N. Drift here
|
|
165
|
+
// re-introduces a fan-out per token (visible cost on group tasks).
|
|
166
|
+
const lookups = calls.filter((c) => c.method === AgentsLookupByName.name);
|
|
167
|
+
expect(lookups).toHaveLength(1);
|
|
168
|
+
expect(lookups[0].params).toEqual({ names: ["bob", "carol"] });
|
|
169
|
+
});
|
|
170
|
+
const duplicateNameDedupesLookup = () => Effect.gen(function* () {
|
|
171
|
+
// P3-2 secondary invariant: duplicate name tokens dedupe in the
|
|
172
|
+
// batched lookup payload (one wire-name per unique value) but
|
|
173
|
+
// resolve to the agent id at every input position. UUID-shaped
|
|
174
|
+
// siblings still skip the wire.
|
|
175
|
+
const { calls, transport } = makeTransportWith(onlyBobLookup());
|
|
176
|
+
yield* runWith(transport, standardArgs(["agent:bob", `agent:${DAVE_AGENT_ID_UUID}`, "agent:bob"]));
|
|
177
|
+
const params = taskCreateParams(calls);
|
|
178
|
+
expect(params.invitedAgentIds).toEqual([
|
|
179
|
+
BOB_AGENT_ID,
|
|
180
|
+
DAVE_AGENT_ID_UUID,
|
|
181
|
+
BOB_AGENT_ID,
|
|
182
|
+
]);
|
|
183
|
+
const lookups = calls.filter((c) => c.method === AgentsLookupByName.name);
|
|
184
|
+
expect(lookups).toHaveLength(1);
|
|
185
|
+
expect(lookups[0].params).toEqual({ names: ["bob"] });
|
|
186
|
+
});
|
|
187
|
+
const callerExcluded = () => Effect.gen(function* () {
|
|
188
|
+
const { calls, transport } = makeTransportWith(onlyBobLookup());
|
|
189
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
190
|
+
const params = taskCreateParams(calls);
|
|
191
|
+
expect(params.invitedAgentIds).not.toContain(INITIATOR_ID);
|
|
192
|
+
expect(params.invitedAgentIds).toEqual([BOB_AGENT_ID]);
|
|
193
|
+
});
|
|
194
|
+
const uuidShorthand = () => Effect.gen(function* () {
|
|
195
|
+
const { calls, transport } = makeTransportWith({});
|
|
196
|
+
yield* runWith(transport, standardArgs([`agent:${DAVE_AGENT_ID_UUID}`]));
|
|
197
|
+
const lookups = calls.filter((c) => c.method === AgentsLookupByName.name);
|
|
198
|
+
expect(lookups).toEqual([]);
|
|
199
|
+
const params = taskCreateParams(calls);
|
|
200
|
+
expect(params.invitedAgentIds).toEqual([DAVE_AGENT_ID_UUID]);
|
|
201
|
+
});
|
|
202
|
+
const zeroParticipants = () => Effect.gen(function* () {
|
|
203
|
+
const { calls, transport } = makeTransportWith({});
|
|
204
|
+
yield* runWith(transport, standardArgs([]));
|
|
205
|
+
const params = taskCreateParams(calls);
|
|
206
|
+
expect(params.invitedAgentIds).toEqual([]);
|
|
207
|
+
// P2-B: zero-participant path MUST omit `participants` from
|
|
208
|
+
// `initialConversation` so the wire payload satisfies
|
|
209
|
+
// `InitialConversationSchema` (participants is Optional with
|
|
210
|
+
// `minItems: 1`). The exact shape pin guards against drift.
|
|
211
|
+
expect(params.initialConversation).toEqual({ name: CONVERSATION_NAME });
|
|
212
|
+
expect("participants" in params.initialConversation).toBe(false);
|
|
213
|
+
const lookups = calls.filter((c) => c.method === AgentsLookupByName.name);
|
|
214
|
+
expect(lookups).toEqual([]);
|
|
215
|
+
});
|
|
216
|
+
describe("moltzap start — participant model", () => {
|
|
217
|
+
beforeEach(installHarness);
|
|
218
|
+
afterEach(restoreHarness);
|
|
219
|
+
it("dm-shape", dmShape);
|
|
220
|
+
it("group-shape, order preserved", groupShape);
|
|
221
|
+
it("caller-excluded", callerExcluded);
|
|
222
|
+
it("uuid-shorthand", uuidShorthand);
|
|
223
|
+
it("zero-participants admitted (plan §R4)", zeroParticipants);
|
|
224
|
+
it("duplicate name tokens dedupe in batched lookup (P3-2)", duplicateNameDedupesLookup);
|
|
225
|
+
});
|
|
226
|
+
// ─── Test bodies: output format ───────────────────────────────────────────
|
|
227
|
+
const outputFormat = () => Effect.gen(function* () {
|
|
228
|
+
const { transport } = makeTransportWith(onlyBobLookup());
|
|
229
|
+
yield* runWith(transport, standardArgs(["agent:bob"], { message: "hello" }));
|
|
230
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${TASK_ID} (conversation: ${CONVERSATION_ID})`);
|
|
231
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Message sent: ${MESSAGE_ID}`);
|
|
232
|
+
});
|
|
233
|
+
describe("moltzap start — output format", () => {
|
|
234
|
+
beforeEach(installHarness);
|
|
235
|
+
afterEach(restoreHarness);
|
|
236
|
+
it("prints exact stdout strings with response IDs", outputFormat);
|
|
237
|
+
});
|
|
238
|
+
// ─── Test bodies: --app-id ────────────────────────────────────────────────
|
|
239
|
+
const defaultAppId = () => Effect.gen(function* () {
|
|
240
|
+
const { calls, transport } = makeTransportWith(onlyBobLookup());
|
|
241
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
242
|
+
expect(taskCreateParams(calls).appId).toBe(DEFAULT_APP_ID);
|
|
243
|
+
});
|
|
244
|
+
const validAppIdOverride = () => Effect.gen(function* () {
|
|
245
|
+
const { calls, transport } = makeTransportWith(onlyBobLookup());
|
|
246
|
+
yield* runWith(transport, standardArgs(["agent:bob"], { appId: VALID_APP_ID_OVERRIDE }));
|
|
247
|
+
expect(taskCreateParams(calls).appId).toBe(VALID_APP_ID_OVERRIDE);
|
|
248
|
+
});
|
|
249
|
+
const invalidAppIdGarbage = () => Effect.gen(function* () {
|
|
250
|
+
const { calls, transport } = makeTransportWith({});
|
|
251
|
+
yield* runWith(transport, standardArgs([], { appId: "not-a-uuid" }));
|
|
252
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
253
|
+
expect(calls).toEqual([]);
|
|
254
|
+
expect(stderrSpy).toHaveBeenCalledWith("Invalid --app-id: not a UUID");
|
|
255
|
+
});
|
|
256
|
+
const invalidAppIdUuidV1 = () => Effect.gen(function* () {
|
|
257
|
+
const { calls, transport } = makeTransportWith({});
|
|
258
|
+
yield* runWith(transport, standardArgs([], { appId: UUID_V1_OVERRIDE }));
|
|
259
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
260
|
+
expect(calls).toEqual([]);
|
|
261
|
+
});
|
|
262
|
+
const nonV4HexDigit = fc
|
|
263
|
+
.integer({ min: 0, max: 15 })
|
|
264
|
+
.filter((n) => n !== 4)
|
|
265
|
+
.map((n) => n.toString(16));
|
|
266
|
+
/**
|
|
267
|
+
* Property body: builds a syntactically-valid UUID with a non-4
|
|
268
|
+
* version digit and asserts the handler exits 64 with zero RPC calls.
|
|
269
|
+
* Runs synchronously via `Effect.runSync` because the test transport
|
|
270
|
+
* never suspends.
|
|
271
|
+
*/
|
|
272
|
+
const expectNonV4Rejected = (digit) => withInstalledHarness(() => {
|
|
273
|
+
const uuid = `11111111-2222-${digit}333-8444-555555555555`;
|
|
274
|
+
const { calls, transport } = makeTransportWith({});
|
|
275
|
+
Effect.runSync(runWith(transport, standardArgs([], { appId: uuid })));
|
|
276
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
277
|
+
expect(calls).toEqual([]);
|
|
278
|
+
});
|
|
279
|
+
const invariantNonV4Rejection = () => {
|
|
280
|
+
fc.assert(fc.property(nonV4HexDigit, expectNonV4Rejected), { numRuns: 30 });
|
|
281
|
+
// Re-install for afterEach symmetry; each property iteration tore
|
|
282
|
+
// down its harness via `withInstalledHarness`, leaving none for the
|
|
283
|
+
// outer afterEach to restore.
|
|
284
|
+
installHarness();
|
|
285
|
+
};
|
|
286
|
+
describe("moltzap start — --app-id", () => {
|
|
287
|
+
beforeEach(installHarness);
|
|
288
|
+
afterEach(restoreHarness);
|
|
289
|
+
it("default sends DEFAULT_APP_ID", defaultAppId);
|
|
290
|
+
it("override sends the provided v4", validAppIdOverride);
|
|
291
|
+
it("garbage UUID -> exit 64, ZERO RPC calls", invalidAppIdGarbage);
|
|
292
|
+
it("UUID v1 -> exit 64, ZERO RPC calls", invalidAppIdUuidV1);
|
|
293
|
+
plainIt("invariant: every non-v4 syntax exits 64 with ZERO RPC calls", invariantNonV4Rejection);
|
|
294
|
+
});
|
|
295
|
+
// ─── Test bodies: failure paths ───────────────────────────────────────────
|
|
296
|
+
const serverRejectsTaskCreate = () => Effect.gen(function* () {
|
|
297
|
+
const { transport } = makeTransportWith({
|
|
298
|
+
...onlyBobLookup(),
|
|
299
|
+
taskCreate: () => new Error("app not installed"),
|
|
300
|
+
});
|
|
301
|
+
yield* runWith(transport, standardArgs(["agent:bob"], { appId: VALID_APP_ID_OVERRIDE }));
|
|
302
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
303
|
+
expect(stderrLines().some((s) => s.startsWith("Failed: "))).toBe(true);
|
|
304
|
+
expect(stdoutSpy).not.toHaveBeenCalled();
|
|
305
|
+
});
|
|
306
|
+
const partialSuccess = () => Effect.gen(function* () {
|
|
307
|
+
const { transport } = makeTransportWith({
|
|
308
|
+
...onlyBobLookup(),
|
|
309
|
+
messagesSend: () => new Error("conv full"),
|
|
310
|
+
});
|
|
311
|
+
yield* runWith(transport, standardArgs(["agent:bob"], { message: "hello" }));
|
|
312
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${TASK_ID} (conversation: ${CONVERSATION_ID})`);
|
|
313
|
+
expect(stderrLines().some((s) => s.startsWith("Error sending message: "))).toBe(true);
|
|
314
|
+
expect(exitSpy).toHaveBeenCalledWith(2);
|
|
315
|
+
});
|
|
316
|
+
const unresolvedLookupEmpty = () => Effect.gen(function* () {
|
|
317
|
+
const { calls, transport } = makeTransportWith({ lookupResults: {} });
|
|
318
|
+
yield* runWith(transport, standardArgs(["agent:unknown"]));
|
|
319
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
320
|
+
expect(mutatingCalls(calls)).toEqual([]);
|
|
321
|
+
expect(stderrLines().some((s) => s.includes("agent:unknown"))).toBe(true);
|
|
322
|
+
});
|
|
323
|
+
const unresolvedShape = () => Effect.gen(function* () {
|
|
324
|
+
const { calls, transport } = makeTransportWith({});
|
|
325
|
+
yield* runWith(transport, standardArgs(["bob"]));
|
|
326
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
327
|
+
expect(calls).toEqual([]);
|
|
328
|
+
});
|
|
329
|
+
const tooManyDistinctNames = () => Effect.gen(function* () {
|
|
330
|
+
// P3-2 carve-out: `AgentsLookupByName.params.names` is capped at
|
|
331
|
+
// `maxItems: 100`. With 101 DISTINCT name tokens, the batched RPC
|
|
332
|
+
// would otherwise fail server-side AJV → opaque exit 1. The
|
|
333
|
+
// pre-RPC cap check surfaces it as exit 64 with a clear message.
|
|
334
|
+
const tokens = Array.from({ length: 101 }, (_, i) => `agent:user${i.toString().padStart(3, "0")}`);
|
|
335
|
+
const { calls, transport } = makeTransportWith({});
|
|
336
|
+
yield* runWith(transport, standardArgs(tokens));
|
|
337
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
338
|
+
// Cap fires BEFORE the RPC — zero wire calls.
|
|
339
|
+
expect(calls).toEqual([]);
|
|
340
|
+
// Structural assertion: diagnostic mentions BOTH the offending
|
|
341
|
+
// count and the schema cap so the user can reduce input directly.
|
|
342
|
+
expect(stderrLines().some((s) => s.includes("Too many") && s.includes("101") && s.includes("100"))).toBe(true);
|
|
343
|
+
});
|
|
344
|
+
/**
|
|
345
|
+
* Property body: any token without the `agent:` prefix fails at the
|
|
346
|
+
* shape check before any RPC. The handler must always exit 64 with
|
|
347
|
+
* zero RPC calls — the resolver short-circuits at the prefix test.
|
|
348
|
+
*/
|
|
349
|
+
const expectNonAgentTokenRejected = (token) => withInstalledHarness(() => {
|
|
350
|
+
const { calls, transport } = makeTransportWith({});
|
|
351
|
+
Effect.runSync(runWith(transport, standardArgs([token])));
|
|
352
|
+
expect(exitSpy).toHaveBeenCalledWith(64);
|
|
353
|
+
expect(calls).toEqual([]);
|
|
354
|
+
});
|
|
355
|
+
const nonAgentToken = fc
|
|
356
|
+
.string({ minLength: 1, maxLength: 30 })
|
|
357
|
+
.filter((s) => !s.startsWith("agent:"));
|
|
358
|
+
const invariantNonAgentRejection = () => {
|
|
359
|
+
fc.assert(fc.property(nonAgentToken, expectNonAgentTokenRejected), {
|
|
360
|
+
numRuns: 30,
|
|
361
|
+
});
|
|
362
|
+
installHarness();
|
|
363
|
+
};
|
|
364
|
+
describe("moltzap start — failure paths", () => {
|
|
365
|
+
beforeEach(installHarness);
|
|
366
|
+
afterEach(restoreHarness);
|
|
367
|
+
it("server-reject TaskCreate -> exit 1", serverRejectsTaskCreate);
|
|
368
|
+
it("partial-success TaskCreate OK + MessagesSend fail -> exit 2", partialSuccess);
|
|
369
|
+
it("unresolved (lookup empty) -> exit 64, ZERO mutating RPCs", unresolvedLookupEmpty);
|
|
370
|
+
it("unresolved (shape) -> exit 64, ZERO RPC calls", unresolvedShape);
|
|
371
|
+
it(">100 distinct names -> exit 64 with TooManyParticipantNamesError diagnostic", tooManyDistinctNames);
|
|
372
|
+
plainIt("invariant: non-agent: prefix tokens exit 64 with ZERO RPC calls", invariantNonAgentRejection);
|
|
373
|
+
});
|
|
374
|
+
// ─── Test bodies: dedup hit (P2-A, spec D2 amendment N6) ─────────────────
|
|
375
|
+
const EXISTING_TASK_ID = "00000000-0000-4000-8000-0000000000d1";
|
|
376
|
+
const EXISTING_CONV_ID_ACTIVE = "00000000-0000-4000-8000-0000000000d2";
|
|
377
|
+
const EXISTING_CONV_ID_OLDER = "00000000-0000-4000-8000-0000000000d3";
|
|
378
|
+
const OTHER_TASK_ID = "00000000-0000-4000-8000-0000000000e9";
|
|
379
|
+
const existingTaskFixture = {
|
|
380
|
+
...taskFixture,
|
|
381
|
+
id: EXISTING_TASK_ID,
|
|
382
|
+
};
|
|
383
|
+
const existingTaskClosedFixture = {
|
|
384
|
+
...existingTaskFixture,
|
|
385
|
+
status: "closed",
|
|
386
|
+
endedAt: NOW_ISO,
|
|
387
|
+
};
|
|
388
|
+
const conversationFixtureActive = {
|
|
389
|
+
...conversationFixture,
|
|
390
|
+
id: EXISTING_CONV_ID_ACTIVE,
|
|
391
|
+
createdAt: "2026-05-19T01:00:00Z",
|
|
392
|
+
};
|
|
393
|
+
const conversationFixtureOlder = {
|
|
394
|
+
...conversationFixture,
|
|
395
|
+
id: EXISTING_CONV_ID_OLDER,
|
|
396
|
+
createdAt: "2026-05-18T00:00:00Z",
|
|
397
|
+
};
|
|
398
|
+
const TASK_CREATE_DEDUP = (task = existingTaskFixture) => () => ({
|
|
399
|
+
task,
|
|
400
|
+
conversation: null,
|
|
401
|
+
});
|
|
402
|
+
const taskConvListItem = (taskId, conversation) => ({
|
|
403
|
+
taskId,
|
|
404
|
+
conversation,
|
|
405
|
+
participants: [INITIATOR_ID, BOB_AGENT_ID],
|
|
406
|
+
});
|
|
407
|
+
const dedupHitSingleConversation = () => Effect.gen(function* () {
|
|
408
|
+
const { calls, transport } = makeTransportWith({
|
|
409
|
+
...onlyBobLookup(),
|
|
410
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
411
|
+
taskConversationList: () => ({
|
|
412
|
+
items: [taskConvListItem(EXISTING_TASK_ID, conversationFixtureActive)],
|
|
413
|
+
}),
|
|
414
|
+
});
|
|
415
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
416
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${EXISTING_TASK_ID} (reusing existing conversation: ${EXISTING_CONV_ID_ACTIVE})`);
|
|
417
|
+
expect(exitSpy).not.toHaveBeenCalled();
|
|
418
|
+
// Must have called TaskConversationList exactly once (single page,
|
|
419
|
+
// single match). Cursor MUST NOT be passed on first page.
|
|
420
|
+
const listCall = findCallOf(calls, TaskConversationList.name);
|
|
421
|
+
expect(listCall).toBeDefined();
|
|
422
|
+
expect(listCall.params).toEqual({ limit: 100 });
|
|
423
|
+
});
|
|
424
|
+
const dedupHitMultipleConversations = () => Effect.gen(function* () {
|
|
425
|
+
// Server-side ordering is activity-desc, so the FIRST item under
|
|
426
|
+
// the target task is the most-recently-active. The handler picks
|
|
427
|
+
// it without re-sorting (per spec D2 amendment N6 tie-break: "first
|
|
428
|
+
// match in server iteration order").
|
|
429
|
+
const { transport } = makeTransportWith({
|
|
430
|
+
...onlyBobLookup(),
|
|
431
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
432
|
+
taskConversationList: () => ({
|
|
433
|
+
items: [
|
|
434
|
+
// Server order: active first, older second.
|
|
435
|
+
taskConvListItem(EXISTING_TASK_ID, conversationFixtureActive),
|
|
436
|
+
taskConvListItem(EXISTING_TASK_ID, conversationFixtureOlder),
|
|
437
|
+
],
|
|
438
|
+
}),
|
|
439
|
+
});
|
|
440
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
441
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${EXISTING_TASK_ID} (reusing existing conversation: ${EXISTING_CONV_ID_ACTIVE})`);
|
|
442
|
+
expect(exitSpy).not.toHaveBeenCalled();
|
|
443
|
+
});
|
|
444
|
+
const dedupHitWithMessage = () => Effect.gen(function* () {
|
|
445
|
+
const { calls, transport } = makeTransportWith({
|
|
446
|
+
...onlyBobLookup(),
|
|
447
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
448
|
+
taskConversationList: () => ({
|
|
449
|
+
items: [taskConvListItem(EXISTING_TASK_ID, conversationFixtureActive)],
|
|
450
|
+
}),
|
|
451
|
+
});
|
|
452
|
+
yield* runWith(transport, standardArgs(["agent:bob"], { message: "hello" }));
|
|
453
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${EXISTING_TASK_ID} (reusing existing conversation: ${EXISTING_CONV_ID_ACTIVE})`);
|
|
454
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Message sent: ${MESSAGE_ID}`);
|
|
455
|
+
// The MessagesSend payload MUST route to the REUSED conversation,
|
|
456
|
+
// not the (null) freshly-created one.
|
|
457
|
+
const sendCall = findCallOf(calls, MessagesSend.name);
|
|
458
|
+
expect(sendCall).toBeDefined();
|
|
459
|
+
expect(sendCall.params.conversationId).toBe(EXISTING_CONV_ID_ACTIVE);
|
|
460
|
+
});
|
|
461
|
+
const dedupHitFiltersOtherTaskAndArchived = () => Effect.gen(function* () {
|
|
462
|
+
// The list mixes items from other tasks AND archived rows under
|
|
463
|
+
// our task — the handler must skip both and find the lone non-
|
|
464
|
+
// archived match.
|
|
465
|
+
const archivedConv = {
|
|
466
|
+
...conversationFixtureOlder,
|
|
467
|
+
archivedAt: NOW_ISO,
|
|
468
|
+
};
|
|
469
|
+
const { transport } = makeTransportWith({
|
|
470
|
+
...onlyBobLookup(),
|
|
471
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
472
|
+
taskConversationList: () => ({
|
|
473
|
+
items: [
|
|
474
|
+
taskConvListItem(OTHER_TASK_ID, conversationFixtureActive),
|
|
475
|
+
taskConvListItem(EXISTING_TASK_ID, archivedConv),
|
|
476
|
+
taskConvListItem(EXISTING_TASK_ID, conversationFixtureActive),
|
|
477
|
+
],
|
|
478
|
+
}),
|
|
479
|
+
});
|
|
480
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
481
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${EXISTING_TASK_ID} (reusing existing conversation: ${EXISTING_CONV_ID_ACTIVE})`);
|
|
482
|
+
});
|
|
483
|
+
const dedupHitTaskClosedNoUsableConversation = () => Effect.gen(function* () {
|
|
484
|
+
// Existing task is reported by the dedup query but all
|
|
485
|
+
// conversations under it are archived → `findReusableConversation`
|
|
486
|
+
// returns null → handler emits closed-task diagnostic + exit 1.
|
|
487
|
+
const archivedConv = {
|
|
488
|
+
...conversationFixtureActive,
|
|
489
|
+
archivedAt: NOW_ISO,
|
|
490
|
+
};
|
|
491
|
+
const { transport } = makeTransportWith({
|
|
492
|
+
...onlyBobLookup(),
|
|
493
|
+
taskCreate: TASK_CREATE_DEDUP(existingTaskClosedFixture),
|
|
494
|
+
taskConversationList: () => ({
|
|
495
|
+
items: [taskConvListItem(EXISTING_TASK_ID, archivedConv)],
|
|
496
|
+
}),
|
|
497
|
+
});
|
|
498
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
499
|
+
expect(stderrLines()).toContain(`Task already exists but is closed: ${EXISTING_TASK_ID}`);
|
|
500
|
+
expect(stdoutSpy).not.toHaveBeenCalled();
|
|
501
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
502
|
+
});
|
|
503
|
+
const dedupHitPaginatesUntilFound = () => Effect.gen(function* () {
|
|
504
|
+
// First page is full of OTHER tasks → handler must follow
|
|
505
|
+
// `nextCursor` to find the target on page two. Pin both calls so a
|
|
506
|
+
// regression that drops pagination support fails the test.
|
|
507
|
+
let callCount = 0;
|
|
508
|
+
const { calls, transport } = makeTransportWith({
|
|
509
|
+
...onlyBobLookup(),
|
|
510
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
511
|
+
taskConversationList: () => {
|
|
512
|
+
callCount += 1;
|
|
513
|
+
if (callCount === 1) {
|
|
514
|
+
return {
|
|
515
|
+
items: [taskConvListItem(OTHER_TASK_ID, conversationFixtureOlder)],
|
|
516
|
+
nextCursor: "2026-05-18T12:00:00Z",
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
items: [
|
|
521
|
+
taskConvListItem(EXISTING_TASK_ID, conversationFixtureActive),
|
|
522
|
+
],
|
|
523
|
+
};
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
527
|
+
expect(callCount).toBe(2);
|
|
528
|
+
expect(stdoutSpy).toHaveBeenCalledWith(`Task started: ${EXISTING_TASK_ID} (reusing existing conversation: ${EXISTING_CONV_ID_ACTIVE})`);
|
|
529
|
+
// Second call MUST forward the cursor returned by the first page.
|
|
530
|
+
const listCalls = calls.filter((c) => c.method === TaskConversationList.name);
|
|
531
|
+
expect(listCalls).toHaveLength(2);
|
|
532
|
+
expect(listCalls[1].params).toEqual({
|
|
533
|
+
limit: 100,
|
|
534
|
+
cursor: "2026-05-18T12:00:00Z",
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
const dedupHitCapsAtMaxPages = () => Effect.gen(function* () {
|
|
538
|
+
// Adversarial server that NEVER returns nextCursor: undefined. The
|
|
539
|
+
// handler MUST stop at `DEDUP_LOOKUP_MAX_PAGES = 10` and surface
|
|
540
|
+
// the closed-task diagnostic; without the cap this loops forever
|
|
541
|
+
// and the test times out. Pins the cap value as a contract.
|
|
542
|
+
let pageCount = 0;
|
|
543
|
+
const { calls, transport } = makeTransportWith({
|
|
544
|
+
...onlyBobLookup(),
|
|
545
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
546
|
+
taskConversationList: () => {
|
|
547
|
+
pageCount += 1;
|
|
548
|
+
return {
|
|
549
|
+
items: [taskConvListItem(OTHER_TASK_ID, conversationFixtureOlder)],
|
|
550
|
+
nextCursor: `cursor-page-${pageCount}`,
|
|
551
|
+
};
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
555
|
+
const listCalls = calls.filter((c) => c.method === TaskConversationList.name);
|
|
556
|
+
expect(listCalls).toHaveLength(10); // DEDUP_LOOKUP_MAX_PAGES
|
|
557
|
+
expect(stderrLines()).toContain(`Task already exists but is closed: ${EXISTING_TASK_ID}`);
|
|
558
|
+
expect(stdoutSpy).not.toHaveBeenCalled();
|
|
559
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
560
|
+
});
|
|
561
|
+
const dedupHitClosedTaskWithMessage = () => Effect.gen(function* () {
|
|
562
|
+
// Partial-failure: TaskCreate dedup-hit + closed-task + --message.
|
|
563
|
+
// The user's message is intentionally DROPPED — handler exits 1
|
|
564
|
+
// before reaching `sendFirstMessage`. Pinned so any future change
|
|
565
|
+
// to add a separate diagnostic ('Message NOT sent: ...') has to
|
|
566
|
+
// update this test, preventing silent regression.
|
|
567
|
+
const archivedConv = {
|
|
568
|
+
...conversationFixtureActive,
|
|
569
|
+
archivedAt: NOW_ISO,
|
|
570
|
+
};
|
|
571
|
+
const { calls, transport } = makeTransportWith({
|
|
572
|
+
...onlyBobLookup(),
|
|
573
|
+
taskCreate: TASK_CREATE_DEDUP(existingTaskClosedFixture),
|
|
574
|
+
taskConversationList: () => ({
|
|
575
|
+
items: [taskConvListItem(EXISTING_TASK_ID, archivedConv)],
|
|
576
|
+
}),
|
|
577
|
+
});
|
|
578
|
+
yield* runWith(transport, standardArgs(["agent:bob"], { message: "hello" }));
|
|
579
|
+
expect(calls.filter((c) => c.method === MessagesSend.name)).toEqual([]);
|
|
580
|
+
expect(stderrLines()).toContain(`Task already exists but is closed: ${EXISTING_TASK_ID}`);
|
|
581
|
+
expect(stdoutSpy).not.toHaveBeenCalled();
|
|
582
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
583
|
+
});
|
|
584
|
+
const dedupHitListRpcFailure = () => Effect.gen(function* () {
|
|
585
|
+
// TaskCreate succeeds (dedup hit). TaskConversationList fails with
|
|
586
|
+
// a wire error (e.g. cursor-format drift). Without the
|
|
587
|
+
// `DedupListFailedError` remap, the user would see
|
|
588
|
+
// `Failed: <list-error>` and assume TaskCreate failed → retry →
|
|
589
|
+
// re-dedup forever. The remap surfaces the existing taskId so the
|
|
590
|
+
// user knows the task is real.
|
|
591
|
+
const { transport } = makeTransportWith({
|
|
592
|
+
...onlyBobLookup(),
|
|
593
|
+
taskCreate: TASK_CREATE_DEDUP(),
|
|
594
|
+
taskConversationList: () => new Error("cursor server-rejected"),
|
|
595
|
+
});
|
|
596
|
+
yield* runWith(transport, standardArgs(["agent:bob"]));
|
|
597
|
+
expect(stderrLines().some((s) => s.startsWith(`Task ${EXISTING_TASK_ID} already exists`) &&
|
|
598
|
+
s.includes("reusable-conversation lookup failed"))).toBe(true);
|
|
599
|
+
expect(stdoutSpy).not.toHaveBeenCalled();
|
|
600
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
601
|
+
});
|
|
602
|
+
describe("moltzap start — dedup hit (P2-A / spec D2 amendment N6)", () => {
|
|
603
|
+
beforeEach(installHarness);
|
|
604
|
+
afterEach(restoreHarness);
|
|
605
|
+
it("single existing conversation -> reuses it", dedupHitSingleConversation);
|
|
606
|
+
it("multiple conversations -> picks first in server iteration order", dedupHitMultipleConversations);
|
|
607
|
+
it("with --message -> sends to reused conversation", dedupHitWithMessage);
|
|
608
|
+
it("filters items from other tasks and archived rows", dedupHitFiltersOtherTaskAndArchived);
|
|
609
|
+
it("task closed / all archived -> exit 1 with stderr diagnostic", dedupHitTaskClosedNoUsableConversation);
|
|
610
|
+
it("paginates via nextCursor when first page misses", dedupHitPaginatesUntilFound);
|
|
611
|
+
it("caps at DEDUP_LOOKUP_MAX_PAGES when server never returns final page", dedupHitCapsAtMaxPages);
|
|
612
|
+
it("closed task + --message -> message dropped, exit 1", dedupHitClosedTaskWithMessage);
|
|
613
|
+
it("TaskConversationList wire failure -> distinct diagnostic, NOT 'Failed: ...'", dedupHitListRpcFailure);
|
|
614
|
+
});
|
|
615
|
+
// ─── Tests: help text ─────────────────────────────────────────────────────
|
|
616
|
+
const helpDescription = () => {
|
|
617
|
+
const desc = JSON.stringify(startCommand);
|
|
618
|
+
expect(desc).toContain(HELP_SYNOPSIS);
|
|
619
|
+
expect(desc).toContain(HELP_MENTIONS_MESSAGES_SEND);
|
|
620
|
+
expect(desc).toContain(HELP_APP_ID_FLAG);
|
|
621
|
+
expect(desc).toContain(HELP_EXIT_CODES_HEADING);
|
|
622
|
+
};
|
|
623
|
+
describe("moltzap start — help", () => {
|
|
624
|
+
plainIt("Command.withDescription contains synopsis + --app-id + exit-code table", helpDescription);
|
|
625
|
+
});
|
|
626
|
+
//# sourceMappingURL=start.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.test.js","sourceRoot":"","sources":["../../../src/cli/commands/start.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { pingCommand } from "./commands/ping.js";
|
|
|
13
13
|
import { presenceCommand } from "./commands/presence.js";
|
|
14
14
|
import { registerCommand } from "./commands/register.js";
|
|
15
15
|
import { sendCommand } from "./commands/send.js";
|
|
16
|
+
import { startCommand } from "./commands/start.js";
|
|
16
17
|
import { statusCommand } from "./commands/status.js";
|
|
17
18
|
import { whoamiCommand } from "./commands/whoami.js";
|
|
18
19
|
import { LoggerLive, minLogLevel } from "./runtime.js";
|
|
@@ -97,6 +98,8 @@ const moltzapBase = Command.make("moltzap", {
|
|
|
97
98
|
agentsCommand,
|
|
98
99
|
// sbd#177 v2 additions:
|
|
99
100
|
messagesCommand,
|
|
101
|
+
// Spec D2 (#599) — architect stub; impl-staff fills the handler body:
|
|
102
|
+
startCommand,
|
|
100
103
|
]));
|
|
101
104
|
const moltzap = Command.provide(moltzapBase, (config) => transportLayerFromConfig(config));
|
|
102
105
|
const cli = Command.run(moltzap, { name: "moltzap", version });
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|