@moltzap/client 2026.414.0 → 2026.425.0
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/channel-core.d.ts +28 -15
- package/dist/channel-core.d.ts.map +1 -1
- package/dist/channel-core.js +113 -74
- package/dist/channel-core.js.map +1 -1
- package/dist/channel-core.test.js +126 -34
- package/dist/channel-core.test.js.map +1 -1
- package/dist/cli/__tests__/cli-multi-agent.int.test.d.ts +2 -0
- package/dist/cli/__tests__/cli-multi-agent.int.test.d.ts.map +1 -0
- package/dist/cli/__tests__/cli-multi-agent.int.test.js +26 -0
- package/dist/cli/__tests__/cli-multi-agent.int.test.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +13 -2
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +30 -18
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/apps.d.ts +96 -0
- package/dist/cli/commands/apps.d.ts.map +1 -0
- package/dist/cli/commands/apps.js +193 -0
- package/dist/cli/commands/apps.js.map +1 -0
- package/dist/cli/commands/apps.test.d.ts +2 -0
- package/dist/cli/commands/apps.test.d.ts.map +1 -0
- package/dist/cli/commands/apps.test.js +220 -0
- package/dist/cli/commands/apps.test.js.map +1 -0
- package/dist/cli/commands/contacts.d.ts +18 -2
- package/dist/cli/commands/contacts.d.ts.map +1 -1
- package/dist/cli/commands/contacts.js +44 -52
- package/dist/cli/commands/contacts.js.map +1 -1
- package/dist/cli/commands/conversations-v2.test.d.ts +2 -0
- package/dist/cli/commands/conversations-v2.test.d.ts.map +1 -0
- package/dist/cli/commands/conversations-v2.test.js +92 -0
- package/dist/cli/commands/conversations-v2.test.js.map +1 -0
- package/dist/cli/commands/conversations.d.ts +73 -3
- package/dist/cli/commands/conversations.d.ts.map +1 -1
- package/dist/cli/commands/conversations.js +157 -108
- package/dist/cli/commands/conversations.js.map +1 -1
- package/dist/cli/commands/invite.d.ts +6 -2
- package/dist/cli/commands/invite.d.ts.map +1 -1
- package/dist/cli/commands/invite.js +8 -6
- package/dist/cli/commands/invite.js.map +1 -1
- package/dist/cli/commands/messages.d.ts +48 -0
- package/dist/cli/commands/messages.d.ts.map +1 -0
- package/dist/cli/commands/messages.js +68 -0
- package/dist/cli/commands/messages.js.map +1 -0
- package/dist/cli/commands/messages.test.d.ts +2 -0
- package/dist/cli/commands/messages.test.d.ts.map +1 -0
- package/dist/cli/commands/messages.test.js +73 -0
- package/dist/cli/commands/messages.test.js.map +1 -0
- package/dist/cli/commands/permissions.d.ts +66 -0
- package/dist/cli/commands/permissions.d.ts.map +1 -0
- package/dist/cli/commands/permissions.js +101 -0
- package/dist/cli/commands/permissions.js.map +1 -0
- package/dist/cli/commands/permissions.test.d.ts +2 -0
- package/dist/cli/commands/permissions.test.d.ts.map +1 -0
- package/dist/cli/commands/permissions.test.js +126 -0
- package/dist/cli/commands/permissions.test.js.map +1 -0
- package/dist/cli/commands/ping.d.ts +6 -2
- package/dist/cli/commands/ping.d.ts.map +1 -1
- package/dist/cli/commands/ping.js +21 -20
- package/dist/cli/commands/ping.js.map +1 -1
- package/dist/cli/commands/presence.d.ts +10 -2
- package/dist/cli/commands/presence.d.ts.map +1 -1
- package/dist/cli/commands/presence.js +27 -15
- package/dist/cli/commands/presence.js.map +1 -1
- package/dist/cli/commands/register.d.ts +24 -2
- package/dist/cli/commands/register.d.ts.map +1 -1
- package/dist/cli/commands/register.js +123 -47
- package/dist/cli/commands/register.js.map +1 -1
- package/dist/cli/commands/register.test.js +45 -27
- package/dist/cli/commands/register.test.js.map +1 -1
- package/dist/cli/commands/send.d.ts +43 -2
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +55 -13
- package/dist/cli/commands/send.js.map +1 -1
- package/dist/cli/commands/send.test.js +20 -19
- package/dist/cli/commands/send.test.js.map +1 -1
- package/dist/cli/commands/status.d.ts +6 -2
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +16 -10
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/whoami.d.ts +7 -2
- package/dist/cli/commands/whoami.d.ts.map +1 -1
- package/dist/cli/commands/whoami.js +13 -7
- package/dist/cli/commands/whoami.js.map +1 -1
- package/dist/cli/config.d.ts +24 -8
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +65 -39
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/config.test.js +12 -10
- package/dist/cli/config.test.js.map +1 -1
- package/dist/cli/http-client.d.ts +6 -2
- package/dist/cli/http-client.d.ts.map +1 -1
- package/dist/cli/http-client.js +25 -24
- package/dist/cli/http-client.js.map +1 -1
- package/dist/cli/index.d.ts +16 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +160 -27
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/profile.d.ts +134 -0
- package/dist/cli/profile.d.ts.map +1 -0
- package/dist/cli/profile.js +217 -0
- package/dist/cli/profile.js.map +1 -0
- package/dist/cli/profile.test.d.ts +2 -0
- package/dist/cli/profile.test.d.ts.map +1 -0
- package/dist/cli/profile.test.js +263 -0
- package/dist/cli/profile.test.js.map +1 -0
- package/dist/cli/runtime.d.ts +34 -0
- package/dist/cli/runtime.d.ts.map +1 -0
- package/dist/cli/runtime.js +94 -0
- package/dist/cli/runtime.js.map +1 -0
- package/dist/cli/socket-client.d.ts +15 -12
- package/dist/cli/socket-client.d.ts.map +1 -1
- package/dist/cli/socket-client.js +72 -75
- package/dist/cli/socket-client.js.map +1 -1
- package/dist/cli/transport.d.ts +181 -0
- package/dist/cli/transport.d.ts.map +1 -0
- package/dist/cli/transport.js +324 -0
- package/dist/cli/transport.js.map +1 -0
- package/dist/cli/transport.test.d.ts +2 -0
- package/dist/cli/transport.test.d.ts.map +1 -0
- package/dist/cli/transport.test.js +197 -0
- package/dist/cli/transport.test.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime/close-info.d.ts +94 -0
- package/dist/runtime/close-info.d.ts.map +1 -0
- package/dist/runtime/close-info.js +109 -0
- package/dist/runtime/close-info.js.map +1 -0
- package/dist/runtime/close-info.test.d.ts +2 -0
- package/dist/runtime/close-info.test.d.ts.map +1 -0
- package/dist/runtime/close-info.test.js +102 -0
- package/dist/runtime/close-info.test.js.map +1 -0
- package/dist/runtime/errors.d.ts +47 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +20 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/errors.test.d.ts +2 -0
- package/dist/runtime/errors.test.d.ts.map +1 -0
- package/dist/runtime/errors.test.js +66 -0
- package/dist/runtime/errors.test.js.map +1 -0
- package/dist/runtime/frame.d.ts +25 -0
- package/dist/runtime/frame.d.ts.map +1 -0
- package/dist/runtime/frame.js +106 -0
- package/dist/runtime/frame.js.map +1 -0
- package/dist/runtime/frame.test.d.ts +2 -0
- package/dist/runtime/frame.test.d.ts.map +1 -0
- package/dist/runtime/frame.test.js +32 -0
- package/dist/runtime/frame.test.js.map +1 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +3 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/refs.d.ts +10 -0
- package/dist/runtime/refs.d.ts.map +1 -0
- package/dist/runtime/refs.js +10 -0
- package/dist/runtime/refs.js.map +1 -0
- package/dist/runtime/runtime.test.d.ts +2 -0
- package/dist/runtime/runtime.test.d.ts.map +1 -0
- package/dist/runtime/runtime.test.js +29 -0
- package/dist/runtime/runtime.test.js.map +1 -0
- package/dist/runtime/subscribers.d.ts +157 -0
- package/dist/runtime/subscribers.d.ts.map +1 -0
- package/dist/runtime/subscribers.js +131 -0
- package/dist/runtime/subscribers.js.map +1 -0
- package/dist/runtime/subscribers.test.d.ts +2 -0
- package/dist/runtime/subscribers.test.d.ts.map +1 -0
- package/dist/runtime/subscribers.test.js +155 -0
- package/dist/runtime/subscribers.test.js.map +1 -0
- package/dist/service.d.ts +68 -17
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +461 -307
- package/dist/service.js.map +1 -1
- package/dist/service.test.js +266 -77
- package/dist/service.test.js.map +1 -1
- package/dist/test/index.d.ts +33 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +44 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test-utils/channel-service-fixture.d.ts +2 -1
- package/dist/test-utils/channel-service-fixture.d.ts.map +1 -1
- package/dist/test-utils/channel-service-fixture.js +31 -11
- package/dist/test-utils/channel-service-fixture.js.map +1 -1
- package/dist/test-utils/conformance-adapter.d.ts +50 -0
- package/dist/test-utils/conformance-adapter.d.ts.map +1 -0
- package/dist/test-utils/conformance-adapter.js +206 -0
- package/dist/test-utils/conformance-adapter.js.map +1 -0
- package/dist/test-utils/fake-service.d.ts +85 -0
- package/dist/test-utils/fake-service.d.ts.map +1 -0
- package/dist/test-utils/fake-service.js +103 -0
- package/dist/test-utils/fake-service.js.map +1 -0
- package/dist/test-utils/index.d.ts +2 -0
- package/dist/test-utils/index.d.ts.map +1 -1
- package/dist/test-utils/index.js +3 -2
- package/dist/test-utils/index.js.map +1 -1
- package/dist/ws-client.d.ts +157 -18
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +432 -94
- package/dist/ws-client.js.map +1 -1
- package/dist/ws-client.test.d.ts +2 -0
- package/dist/ws-client.test.d.ts.map +1 -0
- package/dist/ws-client.test.js +672 -0
- package/dist/ws-client.test.js.map +1 -0
- package/package.json +23 -14
- package/LICENSE +0 -21
- package/dist/__tests__/service.integration.test.d.ts +0 -2
- package/dist/__tests__/service.integration.test.d.ts.map +0 -1
- package/dist/__tests__/service.integration.test.js +0 -1087
- package/dist/__tests__/service.integration.test.js.map +0 -1
- package/dist/cli/commands/delete.d.ts +0 -3
- package/dist/cli/commands/delete.d.ts.map +0 -1
- package/dist/cli/commands/delete.js +0 -10
- package/dist/cli/commands/delete.js.map +0 -1
- package/dist/cli/commands/react.d.ts +0 -3
- package/dist/cli/commands/react.d.ts.map +0 -1
- package/dist/cli/commands/react.js +0 -18
- package/dist/cli/commands/react.js.map +0 -1
|
@@ -1,67 +1,143 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
2
|
import * as os from "node:os";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { Args, Command, Options } from "@effect/cli";
|
|
5
|
+
import { Effect, Option } from "effect";
|
|
6
6
|
import { getServerUrl, updateConfig } from "../config.js";
|
|
7
|
+
import { registerAgent } from "../http-client.js";
|
|
8
|
+
import { emitNoPersist, parseProfileName, writeProfile, } from "../profile.js";
|
|
7
9
|
const NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,30}[a-z0-9]$/;
|
|
8
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Write channel config directly to the OpenClaw JSON file.
|
|
9
12
|
* Avoids `openclaw config set` which triggers both a file-watcher restart
|
|
10
13
|
* AND an internal notification — causing a double-SIGUSR1 race that leaves
|
|
11
14
|
* the gateway stuck in draining mode. Direct file write triggers only the
|
|
12
|
-
* file watcher → one clean restart.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
15
|
+
* file watcher → one clean restart.
|
|
16
|
+
*
|
|
17
|
+
* Per architect design rev 4 finding 2, this side effect is gated by the
|
|
18
|
+
* caller: `--no-persist` skips this call entirely (Invariant §4.4).
|
|
19
|
+
*/
|
|
20
|
+
const writeOpenClawChannelConfig = (account) => Effect.try({
|
|
21
|
+
try: () => {
|
|
22
|
+
const configDir = path.join(os.homedir(), ".openclaw");
|
|
23
|
+
const configPath = path.join(configDir, "openclaw.json");
|
|
24
|
+
let config = {};
|
|
25
|
+
try {
|
|
26
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
const code = err.code;
|
|
30
|
+
if (code !== "ENOENT") {
|
|
31
|
+
console.warn(`moltzap: existing openclaw.json unreadable, starting fresh: ${err instanceof Error ? err.message : String(err)}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const channels = config.channels ?? {};
|
|
35
|
+
channels.moltzap = {
|
|
36
|
+
accounts: [{ id: "default", ...account }],
|
|
37
|
+
};
|
|
38
|
+
config.channels = channels;
|
|
39
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
40
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
41
|
+
},
|
|
42
|
+
catch: (err) => (err instanceof Error ? err : new Error(String(err))),
|
|
43
|
+
});
|
|
44
|
+
const nameArg = Args.text({ name: "name" }).pipe(Args.withDescription("Agent name (lowercase alphanumeric, 3-32 chars)"));
|
|
45
|
+
const inviteCodeArg = Args.text({ name: "invite-code" }).pipe(Args.withDescription("Invite code from your invite URL"));
|
|
46
|
+
const descriptionOption = Options.text("description").pipe(Options.withAlias("d"), Options.withDescription("Agent description"), Options.optional);
|
|
47
|
+
// Spec sbd#177 rev 3 §5.2 barrel edits: --profile and --no-persist.
|
|
48
|
+
//
|
|
49
|
+
// NOTE on `--profile` routing: `register` is the ONE subcommand that
|
|
50
|
+
// consumes `--profile` locally rather than letting `extractGlobalFlags`
|
|
51
|
+
// (cli/index.ts) swallow it for transport selection. Reason: register
|
|
52
|
+
// writes a NEW profile, so the named profile does not yet exist and the
|
|
53
|
+
// transport resolver would reject it as missing. `extractGlobalFlags`
|
|
54
|
+
// detects this case by inspecting argv for the `register` leaf and leaves
|
|
55
|
+
// `--profile` in argv; `@effect/cli` binds it here.
|
|
56
|
+
const profileOption = Options.text("profile").pipe(Options.withDescription("Named profile to register under. Writes the new apiKey to " +
|
|
57
|
+
"`profiles.<name>` in ~/.moltzap/config.json. Omit to overwrite the " +
|
|
58
|
+
"legacy top-level record (the default profile). Other subcommands " +
|
|
59
|
+
"select an existing profile via the global `--profile` flag (see " +
|
|
60
|
+
"`moltzap --help`)."), Options.optional);
|
|
61
|
+
const noPersistFlag = Options.boolean("no-persist").pipe(Options.withDescription("Do not write the registered key to ~/.moltzap/config.json or " +
|
|
62
|
+
"~/.openclaw/openclaw.json. Prints the apiKey and claim URL to stdout " +
|
|
63
|
+
"so the caller can capture them (e.g. into an env var for use with " +
|
|
64
|
+
"`--as $KEY`) without mutating either config tree."));
|
|
65
|
+
/**
|
|
66
|
+
* `moltzap register <name> <invite-code> [-d description] [--profile <name>] [--no-persist]`
|
|
67
|
+
*
|
|
68
|
+
* POST /api/v1/auth/register, then (by default) persist the result into
|
|
69
|
+
* both `~/.moltzap/config.json` and the OpenClaw channel config so the
|
|
70
|
+
* channel picks it up on its next file-watcher cycle.
|
|
71
|
+
*
|
|
72
|
+
* Spec §5.2 extensions:
|
|
73
|
+
* --profile <name> write under `profiles.<name>` instead of legacy top-level
|
|
74
|
+
* --no-persist print result to stdout only; NO writes to either tree
|
|
75
|
+
*
|
|
76
|
+
* `--no-persist` gates BOTH the `~/.moltzap/config.json` write AND the
|
|
77
|
+
* `~/.openclaw/openclaw.json` write (Invariant §4.4 as revised in architect
|
|
78
|
+
* design doc rev 4 finding 2).
|
|
79
|
+
*/
|
|
80
|
+
export const registerCommand = Command.make("register", {
|
|
81
|
+
name: nameArg,
|
|
82
|
+
inviteCode: inviteCodeArg,
|
|
83
|
+
description: descriptionOption,
|
|
84
|
+
profile: profileOption,
|
|
85
|
+
noPersist: noPersistFlag,
|
|
86
|
+
}, ({ name, inviteCode, description, profile, noPersist }) => {
|
|
37
87
|
if (!NAME_PATTERN.test(name)) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
88
|
+
return Effect.sync(() => {
|
|
89
|
+
console.error(`Invalid agent name "${name}". Must be 3-32 chars, lowercase alphanumeric and hyphens, cannot start or end with a hyphen.`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
});
|
|
41
92
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
93
|
+
const desc = Option.isSome(description) ? description.value : undefined;
|
|
94
|
+
return Effect.gen(function* () {
|
|
95
|
+
const result = yield* registerAgent(name, inviteCode, desc);
|
|
96
|
+
const serverUrl = yield* getServerUrl;
|
|
97
|
+
const record = {
|
|
47
98
|
apiKey: result.apiKey,
|
|
48
99
|
agentName: name,
|
|
49
|
-
}));
|
|
50
|
-
writeOpenClawChannelConfig({
|
|
51
|
-
apiKey: result.apiKey,
|
|
52
100
|
serverUrl,
|
|
53
|
-
|
|
54
|
-
}
|
|
101
|
+
registeredAt: new Date().toISOString(),
|
|
102
|
+
};
|
|
103
|
+
if (noPersist) {
|
|
104
|
+
// Invariant §4.4: no writes to ~/.moltzap/ or ~/.openclaw/.
|
|
105
|
+
const emitted = yield* emitNoPersist(record);
|
|
106
|
+
console.log(`Agent "${name}" registered (not persisted).`);
|
|
107
|
+
console.log(` Agent ID: ${result.agentId}`);
|
|
108
|
+
console.log(` API Key: ${emitted.record.apiKey}`);
|
|
109
|
+
console.log(` Server URL: ${emitted.record.serverUrl}`);
|
|
110
|
+
console.log(` Claim URL: ${result.claimUrl}`);
|
|
111
|
+
console.log(`\nShare the claim URL with the agent's owner to verify ownership.`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (Option.isSome(profile)) {
|
|
115
|
+
const profileName = yield* parseProfileName(profile.value);
|
|
116
|
+
yield* writeProfile(profileName, record);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Legacy top-level persistence path (unchanged).
|
|
120
|
+
yield* updateConfig(() => ({
|
|
121
|
+
serverUrl,
|
|
122
|
+
apiKey: result.apiKey,
|
|
123
|
+
agentName: name,
|
|
124
|
+
}));
|
|
125
|
+
yield* writeOpenClawChannelConfig({
|
|
126
|
+
apiKey: result.apiKey,
|
|
127
|
+
serverUrl,
|
|
128
|
+
agentName: name,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
55
131
|
console.log(`Agent "${name}" registered and channel configured.`);
|
|
56
132
|
console.log(` Agent ID: ${result.agentId}`);
|
|
57
133
|
console.log(` API Key: ${result.apiKey}`);
|
|
58
134
|
console.log(` Server URL: ${serverUrl}`);
|
|
59
135
|
console.log(` Claim URL: ${result.claimUrl}`);
|
|
60
136
|
console.log(`\nShare the claim URL with the agent's owner to verify ownership.`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
console.error(`Registration failed: ${
|
|
137
|
+
}).pipe(Effect.catchAll((err) => Effect.sync(() => {
|
|
138
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
139
|
+
console.error(`Registration failed: ${msg}`);
|
|
64
140
|
process.exit(1);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
141
|
+
})));
|
|
142
|
+
}).pipe(Command.withDescription("Register a new agent on MoltZap (requires invite code)"));
|
|
67
143
|
//# sourceMappingURL=register.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/cli/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/cli/commands/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +1,66 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Effect, Option } from "effect";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
3
|
import { registerCommand } from "./register.js";
|
|
3
|
-
const mockRegisterAgent = vi.fn()
|
|
4
|
-
agentId: "agent-123",
|
|
5
|
-
apiKey: "moltzap_agent_testkey",
|
|
6
|
-
claimUrl: "https://moltzap.xyz/claim/tok_abc",
|
|
7
|
-
});
|
|
4
|
+
const mockRegisterAgent = vi.fn();
|
|
8
5
|
vi.mock("../http-client.js", () => ({
|
|
9
|
-
registerAgent: (
|
|
6
|
+
registerAgent: (name, inviteCode, description) => mockRegisterAgent(name, inviteCode, description),
|
|
10
7
|
}));
|
|
11
8
|
vi.mock("../config.js", () => ({
|
|
12
|
-
updateConfig: vi.fn(),
|
|
9
|
+
updateConfig: vi.fn(() => Effect.void),
|
|
10
|
+
getServerUrl: Effect.succeed("wss://test"),
|
|
11
|
+
}));
|
|
12
|
+
// Avoid real fs writes — register calls writeOpenClawChannelConfig which
|
|
13
|
+
// uses node:fs directly. Mock the whole module surface.
|
|
14
|
+
vi.mock("node:fs", () => ({
|
|
15
|
+
readFileSync: vi.fn(() => {
|
|
16
|
+
throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
|
|
17
|
+
}),
|
|
18
|
+
writeFileSync: vi.fn(),
|
|
19
|
+
mkdirSync: vi.fn(),
|
|
13
20
|
}));
|
|
14
|
-
describe("register command", () => {
|
|
21
|
+
describe("register command handler", () => {
|
|
15
22
|
const originalExit = process.exit;
|
|
16
23
|
beforeEach(() => {
|
|
17
24
|
vi.clearAllMocks();
|
|
18
25
|
process.exit = vi.fn();
|
|
26
|
+
mockRegisterAgent.mockImplementation(() => Effect.succeed({
|
|
27
|
+
agentId: "agent-123",
|
|
28
|
+
apiKey: "moltzap_agent_testkey",
|
|
29
|
+
claimUrl: "https://moltzap.xyz/claim/tok_abc",
|
|
30
|
+
}));
|
|
19
31
|
});
|
|
20
32
|
afterEach(() => {
|
|
21
33
|
process.exit = originalExit;
|
|
22
34
|
});
|
|
23
|
-
it("
|
|
24
|
-
await registerCommand.
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
it("passes name, inviteCode, and description through", async () => {
|
|
36
|
+
await Effect.runPromise(registerCommand.handler({
|
|
37
|
+
name: "my-agent",
|
|
38
|
+
inviteCode: "inv_abc123",
|
|
39
|
+
description: Option.none(),
|
|
40
|
+
profile: Option.none(),
|
|
41
|
+
noPersist: false,
|
|
42
|
+
}));
|
|
30
43
|
expect(mockRegisterAgent).toHaveBeenCalledWith("my-agent", "inv_abc123", undefined);
|
|
31
44
|
});
|
|
32
|
-
it("
|
|
33
|
-
await registerCommand.
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
]);
|
|
45
|
+
it("forwards description option when provided", async () => {
|
|
46
|
+
await Effect.runPromise(registerCommand.handler({
|
|
47
|
+
name: "my-agent",
|
|
48
|
+
inviteCode: "inv_abc123",
|
|
49
|
+
description: Option.some("A test agent"),
|
|
50
|
+
profile: Option.none(),
|
|
51
|
+
noPersist: false,
|
|
52
|
+
}));
|
|
41
53
|
expect(mockRegisterAgent).toHaveBeenCalledWith("my-agent", "inv_abc123", "A test agent");
|
|
42
54
|
});
|
|
43
55
|
it("exits with error on registration failure", async () => {
|
|
44
|
-
mockRegisterAgent.
|
|
45
|
-
await registerCommand.
|
|
56
|
+
mockRegisterAgent.mockImplementationOnce(() => Effect.fail(new Error("Invalid invite code")));
|
|
57
|
+
await Effect.runPromise(registerCommand.handler({
|
|
58
|
+
name: "my-agent",
|
|
59
|
+
inviteCode: "inv_bad",
|
|
60
|
+
description: Option.none(),
|
|
61
|
+
profile: Option.none(),
|
|
62
|
+
noPersist: false,
|
|
63
|
+
}));
|
|
46
64
|
expect(process.exit).toHaveBeenCalledWith(1);
|
|
47
65
|
});
|
|
48
66
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.test.js","sourceRoot":"","sources":["../../../src/cli/commands/register.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"register.test.js","sourceRoot":"","sources":["../../../src/cli/commands/register.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,44 @@
|
|
|
1
|
-
import { Command } from "
|
|
2
|
-
|
|
1
|
+
import { Command } from "@effect/cli";
|
|
2
|
+
import { Option } from "effect";
|
|
3
|
+
/**
|
|
4
|
+
* `moltzap send <target> <message> [--reply-to <id>]` — socket-call into
|
|
5
|
+
* the local MoltZapService to enqueue an outbound message. `conv:` prefix
|
|
6
|
+
* addresses a conversation id directly; otherwise `target` is passed as a
|
|
7
|
+
* string the service resolves (typically `agent:<name>` for direct messages
|
|
8
|
+
* or a bare contact name the service resolves against the caller's roster).
|
|
9
|
+
*
|
|
10
|
+
* Identity selection is driven by the GLOBAL flags pre-parsed in
|
|
11
|
+
* `cli/index.ts` before @effect/cli sees argv (see `extractGlobalFlags`):
|
|
12
|
+
*
|
|
13
|
+
* --as <apiKey> Send as the agent owning the given API key.
|
|
14
|
+
* Bypasses the local daemon socket; dials the server
|
|
15
|
+
* directly. Useful in multi-agent workflows where
|
|
16
|
+
* the same host registers more than one agent.
|
|
17
|
+
* --profile <name> Load the named profile from ~/.moltzap/config.json
|
|
18
|
+
* and send as that agent. Short for looking up the
|
|
19
|
+
* apiKey out of the profile and passing it as --as.
|
|
20
|
+
*
|
|
21
|
+
* If neither is provided, the command uses the legacy default profile
|
|
22
|
+
* (top-level apiKey in ~/.moltzap/config.json) — the identity set by the
|
|
23
|
+
* most recent `moltzap register` that did not use `--profile` or
|
|
24
|
+
* `--no-persist`.
|
|
25
|
+
*
|
|
26
|
+
* Examples:
|
|
27
|
+
* moltzap send agent:bob "hello" # default identity
|
|
28
|
+
* moltzap --profile alice send agent:bob "hello" # send as alice
|
|
29
|
+
* moltzap --as $BOB_API_KEY send conv:$CID "ack" # send as bob
|
|
30
|
+
*
|
|
31
|
+
* NOTE: `moltzap send` today routes through the local channel daemon and
|
|
32
|
+
* does NOT yet honor `--as`/`--profile` end-to-end — rewiring legacy
|
|
33
|
+
* commands onto the v2 Transport layer is tracked as a follow-up (see the
|
|
34
|
+
* PR body "Concerns" block). The flag semantics documented above describe
|
|
35
|
+
* the v2 contract; new v2 subcommands (`apps/*`, `permissions/*`,
|
|
36
|
+
* `messages list`, `conversations {get,archive,unarchive}`) honor them
|
|
37
|
+
* today.
|
|
38
|
+
*/
|
|
39
|
+
export declare const sendCommand: Command.Command<"send", never, never, {
|
|
40
|
+
readonly target: string;
|
|
41
|
+
readonly message: string;
|
|
42
|
+
readonly replyTo: Option.Option<string>;
|
|
43
|
+
}>;
|
|
3
44
|
//# sourceMappingURL=send.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAW,MAAM,aAAa,CAAC;AACrD,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAgBxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,WAAW;;;;EAoCvB,CAAC"}
|
|
@@ -1,11 +1,46 @@
|
|
|
1
|
-
import { Command } from "
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { Args, Command, Options } from "@effect/cli";
|
|
2
|
+
import { Effect, Option } from "effect";
|
|
3
|
+
import { request } from "../socket-client.js";
|
|
4
|
+
const targetArg = Args.text({ name: "target" }).pipe(Args.withDescription("Target (agent:<name> or conv:<id>)"));
|
|
5
|
+
const messageArg = Args.text({ name: "message" }).pipe(Args.withDescription("Message text"));
|
|
6
|
+
const replyToOption = Options.text("reply-to").pipe(Options.withDescription("Reply to a specific message"), Options.optional);
|
|
7
|
+
/**
|
|
8
|
+
* `moltzap send <target> <message> [--reply-to <id>]` — socket-call into
|
|
9
|
+
* the local MoltZapService to enqueue an outbound message. `conv:` prefix
|
|
10
|
+
* addresses a conversation id directly; otherwise `target` is passed as a
|
|
11
|
+
* string the service resolves (typically `agent:<name>` for direct messages
|
|
12
|
+
* or a bare contact name the service resolves against the caller's roster).
|
|
13
|
+
*
|
|
14
|
+
* Identity selection is driven by the GLOBAL flags pre-parsed in
|
|
15
|
+
* `cli/index.ts` before @effect/cli sees argv (see `extractGlobalFlags`):
|
|
16
|
+
*
|
|
17
|
+
* --as <apiKey> Send as the agent owning the given API key.
|
|
18
|
+
* Bypasses the local daemon socket; dials the server
|
|
19
|
+
* directly. Useful in multi-agent workflows where
|
|
20
|
+
* the same host registers more than one agent.
|
|
21
|
+
* --profile <name> Load the named profile from ~/.moltzap/config.json
|
|
22
|
+
* and send as that agent. Short for looking up the
|
|
23
|
+
* apiKey out of the profile and passing it as --as.
|
|
24
|
+
*
|
|
25
|
+
* If neither is provided, the command uses the legacy default profile
|
|
26
|
+
* (top-level apiKey in ~/.moltzap/config.json) — the identity set by the
|
|
27
|
+
* most recent `moltzap register` that did not use `--profile` or
|
|
28
|
+
* `--no-persist`.
|
|
29
|
+
*
|
|
30
|
+
* Examples:
|
|
31
|
+
* moltzap send agent:bob "hello" # default identity
|
|
32
|
+
* moltzap --profile alice send agent:bob "hello" # send as alice
|
|
33
|
+
* moltzap --as $BOB_API_KEY send conv:$CID "ack" # send as bob
|
|
34
|
+
*
|
|
35
|
+
* NOTE: `moltzap send` today routes through the local channel daemon and
|
|
36
|
+
* does NOT yet honor `--as`/`--profile` end-to-end — rewiring legacy
|
|
37
|
+
* commands onto the v2 Transport layer is tracked as a follow-up (see the
|
|
38
|
+
* PR body "Concerns" block). The flag semantics documented above describe
|
|
39
|
+
* the v2 contract; new v2 subcommands (`apps/*`, `permissions/*`,
|
|
40
|
+
* `messages list`, `conversations {get,archive,unarchive}`) honor them
|
|
41
|
+
* today.
|
|
42
|
+
*/
|
|
43
|
+
export const sendCommand = Command.make("send", { target: targetArg, message: messageArg, replyTo: replyToOption }, ({ target, message, replyTo }) => {
|
|
9
44
|
const params = {
|
|
10
45
|
parts: [{ type: "text", text: message }],
|
|
11
46
|
};
|
|
@@ -15,9 +50,16 @@ export const sendCommand = new Command("send")
|
|
|
15
50
|
else {
|
|
16
51
|
params.to = target;
|
|
17
52
|
}
|
|
18
|
-
if (
|
|
19
|
-
params.replyToId =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}));
|
|
53
|
+
if (Option.isSome(replyTo))
|
|
54
|
+
params.replyToId = replyTo.value;
|
|
55
|
+
return request("messages/send", params).pipe(Effect.tap((result) => Effect.sync(() => {
|
|
56
|
+
const r = result;
|
|
57
|
+
console.log(`Message sent (id: ${r.message.id})`);
|
|
58
|
+
})), Effect.asVoid, Effect.catchAll((err) => Effect.sync(() => {
|
|
59
|
+
console.error(`Failed: ${err.message}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
})));
|
|
62
|
+
}).pipe(Command.withDescription("Send a message to a conversation (conv:<id>) or DM (agent:<name>). " +
|
|
63
|
+
"Identity follows the global --as / --profile flags; defaults to the " +
|
|
64
|
+
"legacy top-level profile in ~/.moltzap/config.json."));
|
|
23
65
|
//# sourceMappingURL=send.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/cli/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/cli/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAClD,IAAI,CAAC,eAAe,CAAC,oCAAoC,CAAC,CAC3D,CAAC;AAEF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,CACpD,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CACrC,CAAC;AAEF,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CACjD,OAAO,CAAC,eAAe,CAAC,6BAA6B,CAAC,EACtD,OAAO,CAAC,QAAQ,CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CACrC,MAAM,EACN,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,EAClE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;IAC/B,MAAM,MAAM,GAA4B;QACtC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC;IACF,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC;IAE7D,OAAO,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,IAAI,CAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACpB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,MAAM,CAAC,GAAG,MAAqC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC,CAAC,CACH,EACD,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CACH,CACF,CAAC;AACJ,CAAC,CACF,CAAC,IAAI,CACJ,OAAO,CAAC,eAAe,CACrB,qEAAqE;IACnE,sEAAsE;IACtE,qDAAqD,CACxD,CACF,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Effect, Option } from "effect";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
3
|
import { sendCommand } from "./send.js";
|
|
3
|
-
const mockRequest = vi.fn().
|
|
4
|
+
const mockRequest = vi.fn(() => Effect.succeed({ message: { id: "msg-123" } }));
|
|
4
5
|
vi.mock("../socket-client.js", async (importOriginal) => {
|
|
5
6
|
const actual = await importOriginal();
|
|
6
7
|
return {
|
|
@@ -8,44 +9,44 @@ vi.mock("../socket-client.js", async (importOriginal) => {
|
|
|
8
9
|
request: (...args) => mockRequest(...args),
|
|
9
10
|
};
|
|
10
11
|
});
|
|
11
|
-
describe("send command", () => {
|
|
12
|
+
describe("send command handler", () => {
|
|
12
13
|
const originalExit = process.exit;
|
|
13
14
|
beforeEach(() => {
|
|
14
15
|
vi.clearAllMocks();
|
|
15
|
-
mockRequest.
|
|
16
|
+
mockRequest.mockImplementation(() => Effect.succeed({ message: { id: "msg-123" } }));
|
|
16
17
|
process.exit = vi.fn();
|
|
17
18
|
});
|
|
18
19
|
afterEach(() => {
|
|
19
20
|
process.exit = originalExit;
|
|
20
21
|
});
|
|
21
22
|
it("sends to conversation by conv: prefix", async () => {
|
|
22
|
-
await sendCommand.
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
]);
|
|
23
|
+
await Effect.runPromise(sendCommand.handler({
|
|
24
|
+
target: "conv:abc-123",
|
|
25
|
+
message: "Hello world",
|
|
26
|
+
replyTo: Option.none(),
|
|
27
|
+
}));
|
|
28
28
|
expect(mockRequest).toHaveBeenCalledWith("messages/send", {
|
|
29
29
|
conversationId: "abc-123",
|
|
30
30
|
parts: [{ type: "text", text: "Hello world" }],
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
it("sends to agent target without conv: prefix", async () => {
|
|
34
|
-
await sendCommand.
|
|
34
|
+
await Effect.runPromise(sendCommand.handler({
|
|
35
|
+
target: "agent:alice",
|
|
36
|
+
message: "Hi Alice",
|
|
37
|
+
replyTo: Option.none(),
|
|
38
|
+
}));
|
|
35
39
|
expect(mockRequest).toHaveBeenCalledWith("messages/send", {
|
|
36
40
|
to: "agent:alice",
|
|
37
41
|
parts: [{ type: "text", text: "Hi Alice" }],
|
|
38
42
|
});
|
|
39
43
|
});
|
|
40
44
|
it("includes replyToId when --reply-to is provided", async () => {
|
|
41
|
-
await sendCommand.
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
"--reply-to",
|
|
47
|
-
"msg-original",
|
|
48
|
-
]);
|
|
45
|
+
await Effect.runPromise(sendCommand.handler({
|
|
46
|
+
target: "conv:abc-123",
|
|
47
|
+
message: "Reply text",
|
|
48
|
+
replyTo: Option.some("msg-original"),
|
|
49
|
+
}));
|
|
49
50
|
expect(mockRequest).toHaveBeenCalledWith("messages/send", {
|
|
50
51
|
conversationId: "abc-123",
|
|
51
52
|
parts: [{ type: "text", text: "Reply text" }],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.test.js","sourceRoot":"","sources":["../../../src/cli/commands/send.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"send.test.js","sourceRoot":"","sources":["../../../src/cli/commands/send.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
import { Command } from "
|
|
2
|
-
|
|
1
|
+
import { Command } from "@effect/cli";
|
|
2
|
+
/**
|
|
3
|
+
* `moltzap status` — calls the local service's `status` RPC and prints
|
|
4
|
+
* agent id, live connection state, and conversation count.
|
|
5
|
+
*/
|
|
6
|
+
export declare const statusCommand: Command.Command<"status", never, never, {}>;
|
|
3
7
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAUtC;;;GAGG;AACH,eAAO,MAAM,aAAa,6CAsBzB,CAAC"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { Command } from "
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
})
|
|
1
|
+
import { Command } from "@effect/cli";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { request } from "../socket-client.js";
|
|
4
|
+
/**
|
|
5
|
+
* `moltzap status` — calls the local service's `status` RPC and prints
|
|
6
|
+
* agent id, live connection state, and conversation count.
|
|
7
|
+
*/
|
|
8
|
+
export const statusCommand = Command.make("status", {}, () => request("status").pipe(Effect.tap((result) => Effect.sync(() => {
|
|
9
|
+
const r = result;
|
|
10
|
+
console.log(`Agent ID: ${r.agentId ?? "none"}`);
|
|
11
|
+
console.log(`Connected: ${r.connected}`);
|
|
12
|
+
console.log(`Conversations: ${r.conversations}`);
|
|
13
|
+
})), Effect.asVoid, Effect.catchAll((err) => Effect.sync(() => {
|
|
14
|
+
console.error(`Failed: ${err.message}`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
})))).pipe(Command.withDescription("Show agent connection status and conversation summary"));
|
|
11
17
|
//# sourceMappingURL=status.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAQ9C;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,CAC3D,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CACpB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACpB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,MAAM,CAAC,GAAG,MAAsB,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,CACH,EACD,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CACH,CACF,CACF,CAAC,IAAI,CACJ,OAAO,CAAC,eAAe,CACrB,uDAAuD,CACxD,CACF,CAAC"}
|