artemys 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +194 -146
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +446 -379
- package/dist/cli/index.js.map +1 -1
- package/dist/coffeeshop/client.d.ts +158 -0
- package/dist/coffeeshop/client.d.ts.map +1 -0
- package/dist/coffeeshop/client.js +293 -0
- package/dist/coffeeshop/client.js.map +1 -0
- package/dist/coffeeshop/index.d.ts +2 -0
- package/dist/coffeeshop/index.d.ts.map +1 -0
- package/dist/coffeeshop/index.js +2 -0
- package/dist/coffeeshop/index.js.map +1 -0
- package/dist/discovery/agent-card.schema.d.ts +37 -109
- package/dist/discovery/agent-card.schema.d.ts.map +1 -1
- package/dist/discovery/discovery-query.schema.d.ts +6 -15
- package/dist/discovery/discovery-query.schema.d.ts.map +1 -1
- package/dist/discovery/index.d.ts +1 -1
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -1
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/intro-decision.schema.d.ts +9 -11
- package/dist/discovery/intro-decision.schema.d.ts.map +1 -1
- package/dist/discovery/intro-request.schema.d.ts +2 -14
- package/dist/discovery/intro-request.schema.d.ts.map +1 -1
- package/dist/discovery/session-bootstrap.schema.d.ts +86 -66
- package/dist/discovery/session-bootstrap.schema.d.ts.map +1 -1
- package/dist/discovery/session-bootstrap.schema.js +84 -8
- package/dist/discovery/session-bootstrap.schema.js.map +1 -1
- package/dist/mcp-server/index.d.ts +4 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +4 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/mcp-server/persistence.d.ts +37 -0
- package/dist/mcp-server/persistence.d.ts.map +1 -0
- package/dist/mcp-server/persistence.js +309 -0
- package/dist/mcp-server/persistence.js.map +1 -0
- package/dist/mcp-server/resources.d.ts +20 -0
- package/dist/mcp-server/resources.d.ts.map +1 -0
- package/dist/mcp-server/resources.js +49 -0
- package/dist/mcp-server/resources.js.map +1 -0
- package/dist/mcp-server/server.d.ts +33 -0
- package/dist/mcp-server/server.d.ts.map +1 -0
- package/dist/mcp-server/server.js +220 -0
- package/dist/mcp-server/server.js.map +1 -0
- package/dist/mcp-server/state.d.ts +43 -0
- package/dist/mcp-server/state.d.ts.map +1 -0
- package/dist/mcp-server/state.js +111 -0
- package/dist/mcp-server/state.js.map +1 -0
- package/dist/mcp-server/tools/common.d.ts +225 -0
- package/dist/mcp-server/tools/common.d.ts.map +1 -0
- package/dist/mcp-server/tools/common.js +11 -0
- package/dist/mcp-server/tools/common.js.map +1 -0
- package/dist/mcp-server/tools/discovery.d.ts +3 -0
- package/dist/mcp-server/tools/discovery.d.ts.map +1 -0
- package/dist/mcp-server/tools/discovery.js +48 -0
- package/dist/mcp-server/tools/discovery.js.map +1 -0
- package/dist/mcp-server/tools/index.d.ts +4 -0
- package/dist/mcp-server/tools/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/index.js +13 -0
- package/dist/mcp-server/tools/index.js.map +1 -0
- package/dist/mcp-server/tools/intro.d.ts +3 -0
- package/dist/mcp-server/tools/intro.d.ts.map +1 -0
- package/dist/mcp-server/tools/intro.js +53 -0
- package/dist/mcp-server/tools/intro.js.map +1 -0
- package/dist/mcp-server/tools/protocol.d.ts +3 -0
- package/dist/mcp-server/tools/protocol.d.ts.map +1 -0
- package/dist/mcp-server/tools/protocol.js +73 -0
- package/dist/mcp-server/tools/protocol.js.map +1 -0
- package/dist/mcp-server/tools/talent.d.ts +3 -0
- package/dist/mcp-server/tools/talent.d.ts.map +1 -0
- package/dist/mcp-server/tools/talent.js +226 -0
- package/dist/mcp-server/tools/talent.js.map +1 -0
- package/dist/openclaw/index.d.ts +2 -0
- package/dist/openclaw/index.d.ts.map +1 -0
- package/dist/openclaw/index.js +2 -0
- package/dist/openclaw/index.js.map +1 -0
- package/dist/openclaw/skill.d.ts +13 -0
- package/dist/openclaw/skill.d.ts.map +1 -0
- package/dist/openclaw/skill.js +18 -0
- package/dist/openclaw/skill.js.map +1 -0
- package/dist/protocol/consent.schema.d.ts +18 -48
- package/dist/protocol/consent.schema.d.ts.map +1 -1
- package/dist/protocol/consent.schema.js +1 -1
- package/dist/protocol/consent.schema.js.map +1 -1
- package/dist/protocol/dialogue.schema.d.ts +21 -177
- package/dist/protocol/dialogue.schema.d.ts.map +1 -1
- package/dist/protocol/envelope.schema.d.ts +46 -28
- package/dist/protocol/envelope.schema.d.ts.map +1 -1
- package/dist/protocol/errors.d.ts +8 -1
- package/dist/protocol/errors.d.ts.map +1 -1
- package/dist/protocol/handshake.schema.d.ts +130 -385
- package/dist/protocol/handshake.schema.d.ts.map +1 -1
- package/dist/protocol/handshake.schema.js +1 -0
- package/dist/protocol/handshake.schema.js.map +1 -1
- package/dist/protocol/identity.schema.d.ts +44 -94
- package/dist/protocol/identity.schema.d.ts.map +1 -1
- package/dist/protocol/index.d.ts +1 -0
- package/dist/protocol/index.d.ts.map +1 -1
- package/dist/protocol/index.js +1 -0
- package/dist/protocol/index.js.map +1 -1
- package/dist/protocol/message-types.d.ts +14 -1
- package/dist/protocol/message-types.d.ts.map +1 -1
- package/dist/protocol/message.schema.d.ts +100 -715
- package/dist/protocol/message.schema.d.ts.map +1 -1
- package/dist/protocol/resolution.schema.d.ts +22 -268
- package/dist/protocol/resolution.schema.d.ts.map +1 -1
- package/dist/protocol/resolution.schema.js +1 -1
- package/dist/protocol/resolution.schema.js.map +1 -1
- package/dist/protocol/state-machine.d.ts +10 -1
- package/dist/protocol/state-machine.d.ts.map +1 -1
- package/dist/protocol/talent.schema.d.ts +106 -0
- package/dist/protocol/talent.schema.d.ts.map +1 -0
- package/dist/protocol/talent.schema.js +47 -0
- package/dist/protocol/talent.schema.js.map +1 -0
- package/dist/protocol/transport.schema.d.ts +16 -18
- package/dist/protocol/transport.schema.d.ts.map +1 -1
- package/dist/transport/client.d.ts +32 -0
- package/dist/transport/client.d.ts.map +1 -0
- package/dist/transport/client.js +155 -0
- package/dist/transport/client.js.map +1 -0
- package/dist/transport/dedup.d.ts +9 -0
- package/dist/transport/dedup.d.ts.map +1 -0
- package/dist/transport/dedup.js +36 -0
- package/dist/transport/dedup.js.map +1 -0
- package/dist/transport/handler.d.ts +9 -0
- package/dist/transport/handler.d.ts.map +1 -0
- package/dist/transport/handler.js +105 -0
- package/dist/transport/handler.js.map +1 -0
- package/dist/transport/hmac.d.ts +3 -0
- package/dist/transport/hmac.d.ts.map +1 -0
- package/dist/transport/hmac.js +43 -0
- package/dist/transport/hmac.js.map +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +6 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/reference-runner.d.ts +37 -0
- package/dist/transport/reference-runner.d.ts.map +1 -0
- package/dist/transport/reference-runner.js +372 -0
- package/dist/transport/reference-runner.js.map +1 -0
- package/package.json +19 -31
- package/dist/agent/archiver.d.ts +0 -8
- package/dist/agent/archiver.d.ts.map +0 -1
- package/dist/agent/archiver.js +0 -48
- package/dist/agent/archiver.js.map +0 -1
- package/dist/agent/capabilities.d.ts +0 -23
- package/dist/agent/capabilities.d.ts.map +0 -1
- package/dist/agent/capabilities.js +0 -87
- package/dist/agent/capabilities.js.map +0 -1
- package/dist/agent/config.d.ts +0 -60
- package/dist/agent/config.d.ts.map +0 -1
- package/dist/agent/config.js +0 -84
- package/dist/agent/config.js.map +0 -1
- package/dist/agent/context-provider.d.ts +0 -12
- package/dist/agent/context-provider.d.ts.map +0 -1
- package/dist/agent/context-provider.js +0 -34
- package/dist/agent/context-provider.js.map +0 -1
- package/dist/agent/context.d.ts +0 -9
- package/dist/agent/context.d.ts.map +0 -1
- package/dist/agent/context.js +0 -80
- package/dist/agent/context.js.map +0 -1
- package/dist/agent/events.d.ts +0 -62
- package/dist/agent/events.d.ts.map +0 -1
- package/dist/agent/events.js +0 -21
- package/dist/agent/events.js.map +0 -1
- package/dist/agent/index.d.ts +0 -32
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -28
- package/dist/agent/index.js.map +0 -1
- package/dist/agent/mcp.d.ts +0 -16
- package/dist/agent/mcp.d.ts.map +0 -1
- package/dist/agent/mcp.js +0 -69
- package/dist/agent/mcp.js.map +0 -1
- package/dist/agent/notifications/decision-parser.d.ts +0 -10
- package/dist/agent/notifications/decision-parser.d.ts.map +0 -1
- package/dist/agent/notifications/decision-parser.js +0 -21
- package/dist/agent/notifications/decision-parser.js.map +0 -1
- package/dist/agent/notifications/index.d.ts +0 -4
- package/dist/agent/notifications/index.d.ts.map +0 -1
- package/dist/agent/notifications/index.js +0 -3
- package/dist/agent/notifications/index.js.map +0 -1
- package/dist/agent/notifications/opportunity-templates.d.ts +0 -14
- package/dist/agent/notifications/opportunity-templates.d.ts.map +0 -1
- package/dist/agent/notifications/opportunity-templates.js +0 -21
- package/dist/agent/notifications/opportunity-templates.js.map +0 -1
- package/dist/agent/notifications/types.d.ts +0 -16
- package/dist/agent/notifications/types.d.ts.map +0 -1
- package/dist/agent/notifications/types.js +0 -2
- package/dist/agent/notifications/types.js.map +0 -1
- package/dist/agent/providers.d.ts +0 -9
- package/dist/agent/providers.d.ts.map +0 -1
- package/dist/agent/providers.js +0 -29
- package/dist/agent/providers.js.map +0 -1
- package/dist/agent/runtime.d.ts +0 -63
- package/dist/agent/runtime.d.ts.map +0 -1
- package/dist/agent/runtime.js +0 -395
- package/dist/agent/runtime.js.map +0 -1
- package/dist/agent/scanning/index.d.ts +0 -3
- package/dist/agent/scanning/index.d.ts.map +0 -1
- package/dist/agent/scanning/index.js +0 -3
- package/dist/agent/scanning/index.js.map +0 -1
- package/dist/agent/scanning/opportunity-scorer.d.ts +0 -24
- package/dist/agent/scanning/opportunity-scorer.d.ts.map +0 -1
- package/dist/agent/scanning/opportunity-scorer.js +0 -90
- package/dist/agent/scanning/opportunity-scorer.js.map +0 -1
- package/dist/agent/scanning/types.d.ts +0 -65
- package/dist/agent/scanning/types.d.ts.map +0 -1
- package/dist/agent/scanning/types.js +0 -32
- package/dist/agent/scanning/types.js.map +0 -1
- package/dist/agent/scheduler.d.ts +0 -38
- package/dist/agent/scheduler.d.ts.map +0 -1
- package/dist/agent/scheduler.js +0 -125
- package/dist/agent/scheduler.js.map +0 -1
- package/dist/agent/session.d.ts +0 -20
- package/dist/agent/session.d.ts.map +0 -1
- package/dist/agent/session.js +0 -88
- package/dist/agent/session.js.map +0 -1
- package/dist/agent/stores.d.ts +0 -48
- package/dist/agent/stores.d.ts.map +0 -1
- package/dist/agent/stores.js +0 -2
- package/dist/agent/stores.js.map +0 -1
- package/dist/agent/tools/browser/ats-patterns.d.ts +0 -20
- package/dist/agent/tools/browser/ats-patterns.d.ts.map +0 -1
- package/dist/agent/tools/browser/ats-patterns.js +0 -226
- package/dist/agent/tools/browser/ats-patterns.js.map +0 -1
- package/dist/agent/tools/browser/index.d.ts +0 -14
- package/dist/agent/tools/browser/index.d.ts.map +0 -1
- package/dist/agent/tools/browser/index.js +0 -126
- package/dist/agent/tools/browser/index.js.map +0 -1
- package/dist/agent/tools/browser/operator-runtime.d.ts +0 -35
- package/dist/agent/tools/browser/operator-runtime.d.ts.map +0 -1
- package/dist/agent/tools/browser/operator-runtime.js +0 -93
- package/dist/agent/tools/browser/operator-runtime.js.map +0 -1
- package/dist/agent/tools/browser/providers/chrome-mcp.d.ts +0 -3
- package/dist/agent/tools/browser/providers/chrome-mcp.d.ts.map +0 -1
- package/dist/agent/tools/browser/providers/chrome-mcp.js +0 -164
- package/dist/agent/tools/browser/providers/chrome-mcp.js.map +0 -1
- package/dist/agent/tools/browser/providers/playwright.d.ts +0 -7
- package/dist/agent/tools/browser/providers/playwright.d.ts.map +0 -1
- package/dist/agent/tools/browser/providers/playwright.js +0 -619
- package/dist/agent/tools/browser/providers/playwright.js.map +0 -1
- package/dist/agent/tools/browser/types.d.ts +0 -22
- package/dist/agent/tools/browser/types.d.ts.map +0 -1
- package/dist/agent/tools/browser/types.js +0 -15
- package/dist/agent/tools/browser/types.js.map +0 -1
- package/dist/agent/tools/cancel-task.d.ts +0 -4
- package/dist/agent/tools/cancel-task.d.ts.map +0 -1
- package/dist/agent/tools/cancel-task.js +0 -29
- package/dist/agent/tools/cancel-task.js.map +0 -1
- package/dist/agent/tools/career-advice.d.ts +0 -3
- package/dist/agent/tools/career-advice.d.ts.map +0 -1
- package/dist/agent/tools/career-advice.js +0 -49
- package/dist/agent/tools/career-advice.js.map +0 -1
- package/dist/agent/tools/index.d.ts +0 -15
- package/dist/agent/tools/index.d.ts.map +0 -1
- package/dist/agent/tools/index.js +0 -94
- package/dist/agent/tools/index.js.map +0 -1
- package/dist/agent/tools/job-search.d.ts +0 -3
- package/dist/agent/tools/job-search.d.ts.map +0 -1
- package/dist/agent/tools/job-search.js +0 -77
- package/dist/agent/tools/job-search.js.map +0 -1
- package/dist/agent/tools/list-tasks.d.ts +0 -4
- package/dist/agent/tools/list-tasks.d.ts.map +0 -1
- package/dist/agent/tools/list-tasks.js +0 -24
- package/dist/agent/tools/list-tasks.js.map +0 -1
- package/dist/agent/tools/market-data.d.ts +0 -8
- package/dist/agent/tools/market-data.d.ts.map +0 -1
- package/dist/agent/tools/market-data.js +0 -133
- package/dist/agent/tools/market-data.js.map +0 -1
- package/dist/agent/tools/memory-write.d.ts +0 -3
- package/dist/agent/tools/memory-write.d.ts.map +0 -1
- package/dist/agent/tools/memory-write.js +0 -48
- package/dist/agent/tools/memory-write.js.map +0 -1
- package/dist/agent/tools/resume.d.ts +0 -3
- package/dist/agent/tools/resume.d.ts.map +0 -1
- package/dist/agent/tools/resume.js +0 -70
- package/dist/agent/tools/resume.js.map +0 -1
- package/dist/agent/tools/schedule-task.d.ts +0 -4
- package/dist/agent/tools/schedule-task.d.ts.map +0 -1
- package/dist/agent/tools/schedule-task.js +0 -39
- package/dist/agent/tools/schedule-task.js.map +0 -1
- package/dist/agent/tools/shell.d.ts +0 -6
- package/dist/agent/tools/shell.d.ts.map +0 -1
- package/dist/agent/tools/shell.js +0 -66
- package/dist/agent/tools/shell.js.map +0 -1
- package/dist/agent/tools/web-search.d.ts +0 -6
- package/dist/agent/tools/web-search.d.ts.map +0 -1
- package/dist/agent/tools/web-search.js +0 -73
- package/dist/agent/tools/web-search.js.map +0 -1
- package/dist/agent/types.d.ts +0 -103
- package/dist/agent/types.d.ts.map +0 -1
- package/dist/agent/types.js +0 -11
- package/dist/agent/types.js.map +0 -1
- package/dist/channels/index.d.ts +0 -10
- package/dist/channels/index.d.ts.map +0 -1
- package/dist/channels/index.js +0 -15
- package/dist/channels/index.js.map +0 -1
- package/dist/channels/telegram.d.ts +0 -21
- package/dist/channels/telegram.d.ts.map +0 -1
- package/dist/channels/telegram.js +0 -255
- package/dist/channels/telegram.js.map +0 -1
- package/dist/channels/types.d.ts +0 -24
- package/dist/channels/types.d.ts.map +0 -1
- package/dist/channels/types.js +0 -2
- package/dist/channels/types.js.map +0 -1
- package/dist/cli/templates/HEARTBEAT.md +0 -6
- package/dist/cli/templates/MEMORY.md +0 -6
- package/dist/cli/templates/PREFERENCES.md +0 -40
- package/dist/cli/templates/PROFILE.md +0 -26
- package/dist/cli/templates/SOUL.md +0 -23
- package/dist/connectors/google-calendar.d.ts +0 -8
- package/dist/connectors/google-calendar.d.ts.map +0 -1
- package/dist/connectors/google-calendar.js +0 -23
- package/dist/connectors/google-calendar.js.map +0 -1
- package/dist/connectors/google-gmail.d.ts +0 -8
- package/dist/connectors/google-gmail.d.ts.map +0 -1
- package/dist/connectors/google-gmail.js +0 -30
- package/dist/connectors/google-gmail.js.map +0 -1
- package/dist/connectors/google-oauth.d.ts +0 -17
- package/dist/connectors/google-oauth.d.ts.map +0 -1
- package/dist/connectors/google-oauth.js +0 -52
- package/dist/connectors/google-oauth.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -5
- package/dist/connectors/index.d.ts.map +0 -1
- package/dist/connectors/index.js +0 -5
- package/dist/connectors/index.js.map +0 -1
- package/dist/connectors/types.d.ts +0 -20
- package/dist/connectors/types.d.ts.map +0 -1
- package/dist/connectors/types.js +0 -5
- package/dist/connectors/types.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,434 +1,501 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
console.log(" 3. Edit ~/.artemys/SOUL.md to customize Artie's personality");
|
|
47
|
-
console.log(" 4. Run: artemys doctor");
|
|
48
|
-
console.log(" 5. Run: artemys start\n");
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { CoffeeShopClient } from "../coffeeshop/index.js";
|
|
6
|
+
import { AgentCardSchema, DiscoveryQuerySchema, } from "../discovery/index.js";
|
|
7
|
+
import { ConversationTracker, ProfileStore, SqliteMcpPersistence, createPersistentConversationTracker, createPersistentProfileStore, startArtemysMcpServer, } from "../mcp-server/index.js";
|
|
8
|
+
import { registerTalentTools } from "../mcp-server/tools/talent.js";
|
|
9
|
+
import { ProtocolTransportClient } from "../transport/index.js";
|
|
10
|
+
const DEFAULT_COFFEESHOP_URL = "https://coffeeshop.artemys.ai";
|
|
11
|
+
const DEFAULT_MAX_TRACKED_CONVERSATIONS = 1_000;
|
|
12
|
+
const DEFAULT_CONVERSATION_TTL_MS = 24 * 60 * 60 * 1000;
|
|
13
|
+
function parseArgs(argv) {
|
|
14
|
+
const positionals = [];
|
|
15
|
+
const flags = {};
|
|
16
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
17
|
+
const token = argv[index];
|
|
18
|
+
if (!token.startsWith("--")) {
|
|
19
|
+
positionals.push(token);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const key = token.slice(2);
|
|
23
|
+
const next = argv[index + 1];
|
|
24
|
+
if (!next || next.startsWith("--")) {
|
|
25
|
+
flags[key] = true;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (key === "capability") {
|
|
29
|
+
const current = flags[key];
|
|
30
|
+
if (Array.isArray(current)) {
|
|
31
|
+
current.push(next);
|
|
32
|
+
}
|
|
33
|
+
else if (typeof current === "string") {
|
|
34
|
+
flags[key] = [current, next];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
flags[key] = [next];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
flags[key] = next;
|
|
42
|
+
}
|
|
43
|
+
index += 1;
|
|
44
|
+
}
|
|
45
|
+
return { positionals, flags };
|
|
49
46
|
}
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
function getFlagString(flags, key) {
|
|
48
|
+
const value = flags[key];
|
|
49
|
+
return typeof value === "string" ? value : undefined;
|
|
52
50
|
}
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
let config;
|
|
58
|
-
try {
|
|
59
|
-
config = await loadConfig();
|
|
51
|
+
function getFlagBoolean(flags, key) {
|
|
52
|
+
const value = flags[key];
|
|
53
|
+
if (typeof value === "boolean") {
|
|
54
|
+
return value;
|
|
60
55
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
if (typeof value === "string") {
|
|
57
|
+
const normalized = value.trim().toLowerCase();
|
|
58
|
+
if (normalized === "true") {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (normalized === "false") {
|
|
62
|
+
return false;
|
|
66
63
|
}
|
|
67
|
-
throw err;
|
|
68
64
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
function getPersistOption(flags) {
|
|
68
|
+
const value = flags.persist;
|
|
69
|
+
if (typeof value === "boolean") {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
if (typeof value === "string") {
|
|
73
|
+
const trimmed = value.trim();
|
|
74
|
+
if (trimmed.length === 0) {
|
|
75
|
+
return true;
|
|
80
76
|
}
|
|
81
|
-
|
|
77
|
+
const normalized = trimmed.toLowerCase();
|
|
78
|
+
if (normalized === "true") {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (normalized === "false") {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return trimmed;
|
|
82
85
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
function getCsvFlagList(flags, key) {
|
|
89
|
+
const value = getFlagString(flags, key);
|
|
90
|
+
if (!value) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const items = value
|
|
94
|
+
.split(",")
|
|
95
|
+
.map((entry) => entry.trim())
|
|
96
|
+
.filter((entry) => entry.length > 0);
|
|
97
|
+
return items.length > 0 ? items : undefined;
|
|
92
98
|
}
|
|
93
99
|
function printHelp() {
|
|
94
100
|
console.log(`
|
|
95
|
-
artemys
|
|
101
|
+
artemys - Protocol + Coffee Shop + MCP Server SDK CLI
|
|
96
102
|
|
|
97
103
|
Commands:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
mcp-server Start Artemys MCP server
|
|
105
|
+
talent Candidate talent workflow commands
|
|
106
|
+
register Register an agent card with Coffee Shop
|
|
107
|
+
discover Discover agents via Coffee Shop
|
|
108
|
+
rotate-key Rotate Coffee Shop API key
|
|
109
|
+
intro-events Show intro lifecycle events
|
|
110
|
+
version Show CLI version
|
|
111
|
+
help Show this help message
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
artemys mcp-server --agent-card ./agent-card.json
|
|
115
|
+
artemys mcp-server --agent-card ./agent-card.json --persist
|
|
116
|
+
artemys register --agent-card ./agent-card.json
|
|
117
|
+
artemys discover --requester-agent-id agent-123 --role talent_agent
|
|
118
|
+
artemys talent search --agent-card ./agent-card.json --role-keywords backend,platform --remote-ok
|
|
119
|
+
artemys talent apply --agent-card ./agent-card.json --target-agent-id talent-1 --target-endpoint https://talent.example.com/messages --job-posting-ref job-123 --persist
|
|
120
|
+
artemys talent profile --agent-card ./agent-card.json --profile-file ./candidate-profile.json --persist
|
|
121
|
+
artemys rotate-key --agent-id agent-123 --api-key old-key
|
|
122
|
+
artemys intro-events --intro-id intro-abc --api-key key
|
|
123
|
+
`);
|
|
124
|
+
}
|
|
125
|
+
function printTalentHelp() {
|
|
126
|
+
console.log(`
|
|
127
|
+
artemys talent - Candidate talent workflow commands
|
|
128
|
+
|
|
129
|
+
Subcommands:
|
|
130
|
+
search Discover opportunities from talent agents
|
|
131
|
+
apply Express interest in a specific job posting
|
|
132
|
+
status Check tracked conversation status
|
|
133
|
+
profile Update stored candidate profile
|
|
102
134
|
help Show this help message
|
|
103
135
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
136
|
+
Examples:
|
|
137
|
+
artemys talent search --agent-card ./agent-card.json --role-keywords backend,platform --remote-ok --limit 20
|
|
138
|
+
artemys talent apply --agent-card ./agent-card.json --target-agent-id talent-1 --target-endpoint https://talent.example.com/messages --job-posting-ref job-123 --match-reasoning "Strong backend fit"
|
|
139
|
+
artemys talent status --agent-card ./agent-card.json --status-filter dialogue_active --persist
|
|
140
|
+
artemys talent profile --agent-card ./agent-card.json --profile-file ./candidate-profile.json --sync-agent-card --persist ~/.artemys/state.db
|
|
141
|
+
|
|
142
|
+
Common flags:
|
|
143
|
+
--agent-card <path> Required for all talent subcommands except help
|
|
144
|
+
--coffeeshop-url <url> Override Coffee Shop base URL
|
|
145
|
+
--persist [path] Persist profile + conversations to SQLite (default: ~/.artemys/state.db)
|
|
110
146
|
`);
|
|
111
147
|
}
|
|
112
|
-
function
|
|
148
|
+
async function readAgentCardFromPath(pathValue) {
|
|
149
|
+
const raw = await readFile(pathValue, "utf-8");
|
|
150
|
+
const parsed = JSON.parse(raw);
|
|
151
|
+
return AgentCardSchema.parse(parsed);
|
|
152
|
+
}
|
|
153
|
+
function buildNetworkDeps(args, agentCard) {
|
|
154
|
+
const coffeeShopUrl = getFlagString(args.flags, "coffeeshop-url") ?? DEFAULT_COFFEESHOP_URL;
|
|
155
|
+
const hasCoffeeShopApiKey = typeof process.env.ARTEMYS_COFFEESHOP_API_KEY === "string" &&
|
|
156
|
+
process.env.ARTEMYS_COFFEESHOP_API_KEY.length > 0;
|
|
157
|
+
const coffeeShopClient = new CoffeeShopClient({
|
|
158
|
+
baseUrl: coffeeShopUrl,
|
|
159
|
+
apiKey: process.env.ARTEMYS_COFFEESHOP_API_KEY,
|
|
160
|
+
agentId: agentCard.agent_id,
|
|
161
|
+
});
|
|
162
|
+
const transportClient = new ProtocolTransportClient({
|
|
163
|
+
agentId: agentCard.agent_id,
|
|
164
|
+
getSharedSecret: loadSharedSecretResolver({
|
|
165
|
+
coffeeShopClient: hasCoffeeShopApiKey ? coffeeShopClient : undefined,
|
|
166
|
+
}),
|
|
167
|
+
});
|
|
113
168
|
return {
|
|
114
|
-
|
|
115
|
-
|
|
169
|
+
coffeeShopClient,
|
|
170
|
+
transportClient,
|
|
171
|
+
hasCoffeeShopApiKey,
|
|
116
172
|
};
|
|
117
173
|
}
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
console.log("\nArtemys doctor\n");
|
|
132
|
-
for (const check of checks) {
|
|
133
|
-
const icon = check.status === "pass" ? "PASS" : "FAIL";
|
|
134
|
-
const fix = check.fixable
|
|
135
|
-
? check.fixed
|
|
136
|
-
? " (fixed)"
|
|
137
|
-
: " (fixable with --fix)"
|
|
138
|
-
: "";
|
|
139
|
-
const target = check.path ? ` [${check.path}]` : "";
|
|
140
|
-
console.log(`${icon} [${check.severity}] ${check.id}: ${check.message}${fix}${target}`);
|
|
141
|
-
}
|
|
142
|
-
console.log("");
|
|
143
|
-
if (failing.length === 0) {
|
|
144
|
-
console.log("Doctor check passed: runtime looks healthy.\n");
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
console.log(`Doctor found ${failing.length} issue(s), including ${criticalFailures.length} critical.`);
|
|
148
|
-
console.log("Use `artemys doctor --fix` to apply safe automatic repairs.\n");
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if (failing.length > 0) {
|
|
152
|
-
process.exit(1);
|
|
174
|
+
function buildTalentState(flags) {
|
|
175
|
+
const persistOption = getPersistOption(flags);
|
|
176
|
+
if (!persistOption) {
|
|
177
|
+
return {
|
|
178
|
+
tracker: new ConversationTracker({
|
|
179
|
+
maxConversations: DEFAULT_MAX_TRACKED_CONVERSATIONS,
|
|
180
|
+
conversationTtlMs: DEFAULT_CONVERSATION_TTL_MS,
|
|
181
|
+
}),
|
|
182
|
+
profileStore: new ProfileStore(),
|
|
183
|
+
close: () => { },
|
|
184
|
+
};
|
|
153
185
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const checks = [];
|
|
157
|
-
const configExists = await pathExists(CONFIG_PATH);
|
|
158
|
-
checks.push({
|
|
159
|
-
id: "config.exists",
|
|
160
|
-
severity: "critical",
|
|
161
|
-
status: configExists ? "pass" : "fail",
|
|
162
|
-
message: configExists
|
|
163
|
-
? "Config file exists"
|
|
164
|
-
: "Config file is missing. Run `artemys onboard` first.",
|
|
165
|
-
path: CONFIG_PATH,
|
|
166
|
-
fixable: false,
|
|
167
|
-
fixed: false,
|
|
186
|
+
const persistence = new SqliteMcpPersistence({
|
|
187
|
+
path: typeof persistOption === "string" ? persistOption : undefined,
|
|
168
188
|
});
|
|
169
|
-
|
|
170
|
-
|
|
189
|
+
return {
|
|
190
|
+
tracker: createPersistentConversationTracker(persistence, {
|
|
191
|
+
maxConversations: DEFAULT_MAX_TRACKED_CONVERSATIONS,
|
|
192
|
+
conversationTtlMs: DEFAULT_CONVERSATION_TTL_MS,
|
|
193
|
+
}),
|
|
194
|
+
profileStore: createPersistentProfileStore(persistence),
|
|
195
|
+
close: () => {
|
|
196
|
+
persistence.close();
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function buildTalentToolHandlers(deps) {
|
|
201
|
+
const handlers = new Map();
|
|
202
|
+
registerTalentTools({
|
|
203
|
+
registerTool: (name, _config, handler) => {
|
|
204
|
+
handlers.set(name, handler);
|
|
205
|
+
},
|
|
206
|
+
}, deps);
|
|
207
|
+
return handlers;
|
|
208
|
+
}
|
|
209
|
+
function extractToolResponseData(response) {
|
|
210
|
+
const structuredData = response.structuredContent?.data;
|
|
211
|
+
if (structuredData !== undefined) {
|
|
212
|
+
return structuredData;
|
|
213
|
+
}
|
|
214
|
+
const textContent = response.content[0]?.text;
|
|
215
|
+
if (typeof textContent !== "string" || textContent.length === 0) {
|
|
216
|
+
return null;
|
|
171
217
|
}
|
|
172
|
-
let rawConfig;
|
|
173
218
|
try {
|
|
174
|
-
|
|
175
|
-
rawConfig = JSON.parse(raw);
|
|
176
|
-
checks.push({
|
|
177
|
-
id: "config.valid_json",
|
|
178
|
-
severity: "critical",
|
|
179
|
-
status: "pass",
|
|
180
|
-
message: "Config JSON is valid",
|
|
181
|
-
path: CONFIG_PATH,
|
|
182
|
-
fixable: false,
|
|
183
|
-
fixed: false,
|
|
184
|
-
});
|
|
219
|
+
return JSON.parse(textContent);
|
|
185
220
|
}
|
|
186
221
|
catch {
|
|
187
|
-
|
|
188
|
-
id: "config.valid_json",
|
|
189
|
-
severity: "critical",
|
|
190
|
-
status: "fail",
|
|
191
|
-
message: "Config file is not valid JSON",
|
|
192
|
-
path: CONFIG_PATH,
|
|
193
|
-
fixable: false,
|
|
194
|
-
fixed: false,
|
|
195
|
-
});
|
|
196
|
-
return checks;
|
|
197
|
-
}
|
|
198
|
-
// At least one provider auth required
|
|
199
|
-
const hasAnthropic = !!asString(rawConfig.anthropic_api_key) || !!asString(rawConfig.anthropic_auth_token);
|
|
200
|
-
const hasOpenai = !!asString(rawConfig.openai_api_key) || !!asString(rawConfig.openai_auth_token);
|
|
201
|
-
checks.push({
|
|
202
|
-
id: "config.required.provider_auth",
|
|
203
|
-
severity: "critical",
|
|
204
|
-
status: hasAnthropic || hasOpenai ? "pass" : "fail",
|
|
205
|
-
message: hasAnthropic || hasOpenai
|
|
206
|
-
? `Provider auth configured (anthropic: ${hasAnthropic}, openai: ${hasOpenai})`
|
|
207
|
-
: "No provider auth configured. Set at least one of: anthropic_api_key, openai_api_key",
|
|
208
|
-
path: CONFIG_PATH,
|
|
209
|
-
fixable: false,
|
|
210
|
-
fixed: false,
|
|
211
|
-
});
|
|
212
|
-
const botToken = asString(rawConfig.telegram_bot_token);
|
|
213
|
-
checks.push({
|
|
214
|
-
id: "config.required.telegram_bot_token",
|
|
215
|
-
severity: "critical",
|
|
216
|
-
status: botToken ? "pass" : "fail",
|
|
217
|
-
message: botToken ? "telegram_bot_token is set" : "telegram_bot_token is missing or empty",
|
|
218
|
-
path: CONFIG_PATH,
|
|
219
|
-
fixable: false,
|
|
220
|
-
fixed: false,
|
|
221
|
-
});
|
|
222
|
-
// Validate model string has provider prefix
|
|
223
|
-
const model = asString(rawConfig.model) ?? "anthropic:claude-haiku-4-5-20251001";
|
|
224
|
-
checks.push({
|
|
225
|
-
id: "config.model_format",
|
|
226
|
-
severity: "warning",
|
|
227
|
-
status: model.includes(":") ? "pass" : "fail",
|
|
228
|
-
message: model.includes(":")
|
|
229
|
-
? `Model is provider-prefixed: ${model}`
|
|
230
|
-
: `Model "${model}" should be provider-prefixed (e.g. "anthropic:claude-haiku-4-5-20251001")`,
|
|
231
|
-
fixable: false,
|
|
232
|
-
fixed: false,
|
|
233
|
-
});
|
|
234
|
-
const profilePath = expandPath(asString(rawConfig.profile_path) ?? "~/.artemys/PROFILE.md");
|
|
235
|
-
const preferencesPath = expandPath(asString(rawConfig.preferences_path) ?? "~/.artemys/PREFERENCES.md");
|
|
236
|
-
const soulPath = path.join(ARTEMYS_DIR, "SOUL.md");
|
|
237
|
-
const storagePath = expandPath(asString(rawConfig.storage_path) ?? "~/.artemys/sessions");
|
|
238
|
-
checks.push(await ensureFileCheck({
|
|
239
|
-
id: "files.profile",
|
|
240
|
-
targetPath: profilePath,
|
|
241
|
-
templateName: "PROFILE.md",
|
|
242
|
-
options,
|
|
243
|
-
message: "Profile file exists",
|
|
244
|
-
}));
|
|
245
|
-
checks.push(await ensureFileCheck({
|
|
246
|
-
id: "files.preferences",
|
|
247
|
-
targetPath: preferencesPath,
|
|
248
|
-
templateName: "PREFERENCES.md",
|
|
249
|
-
options,
|
|
250
|
-
message: "Preferences file exists",
|
|
251
|
-
}));
|
|
252
|
-
checks.push(await ensureFileCheck({
|
|
253
|
-
id: "files.soul",
|
|
254
|
-
targetPath: soulPath,
|
|
255
|
-
templateName: "SOUL.md",
|
|
256
|
-
options,
|
|
257
|
-
message: "Soul file exists",
|
|
258
|
-
}));
|
|
259
|
-
const storageExists = await pathExists(storagePath);
|
|
260
|
-
let storageFixed = false;
|
|
261
|
-
if (!storageExists && options.fix) {
|
|
262
|
-
await fs.mkdir(storagePath, { recursive: true });
|
|
263
|
-
storageFixed = true;
|
|
264
|
-
}
|
|
265
|
-
checks.push({
|
|
266
|
-
id: "storage.exists",
|
|
267
|
-
severity: "warning",
|
|
268
|
-
status: storageExists || storageFixed ? "pass" : "fail",
|
|
269
|
-
message: storageExists || storageFixed
|
|
270
|
-
? "Session storage directory exists"
|
|
271
|
-
: "Session storage directory is missing",
|
|
272
|
-
path: storagePath,
|
|
273
|
-
fixable: true,
|
|
274
|
-
fixed: storageFixed,
|
|
275
|
-
});
|
|
276
|
-
const writable = await isWritable(storagePath);
|
|
277
|
-
checks.push({
|
|
278
|
-
id: "storage.writable",
|
|
279
|
-
severity: "critical",
|
|
280
|
-
status: writable ? "pass" : "fail",
|
|
281
|
-
message: writable
|
|
282
|
-
? "Session storage directory is writable"
|
|
283
|
-
: "Session storage directory is not writable",
|
|
284
|
-
path: storagePath,
|
|
285
|
-
fixable: false,
|
|
286
|
-
fixed: false,
|
|
287
|
-
});
|
|
288
|
-
if (process.platform !== "win32") {
|
|
289
|
-
const mode = await fileMode(CONFIG_PATH);
|
|
290
|
-
const permissive = mode !== null ? (mode & 0o077) > 0 : false;
|
|
291
|
-
let fixed = false;
|
|
292
|
-
if (permissive && options.fix) {
|
|
293
|
-
await fs.chmod(CONFIG_PATH, 0o600);
|
|
294
|
-
fixed = true;
|
|
295
|
-
}
|
|
296
|
-
checks.push({
|
|
297
|
-
id: "config.permissions",
|
|
298
|
-
severity: "warning",
|
|
299
|
-
status: permissive && !fixed ? "fail" : "pass",
|
|
300
|
-
message: permissive && !fixed
|
|
301
|
-
? "Config permissions are too open; recommend chmod 600"
|
|
302
|
-
: "Config permissions are restricted",
|
|
303
|
-
path: CONFIG_PATH,
|
|
304
|
-
fixable: true,
|
|
305
|
-
fixed,
|
|
306
|
-
});
|
|
222
|
+
return textContent;
|
|
307
223
|
}
|
|
308
|
-
return checks;
|
|
309
224
|
}
|
|
310
|
-
async function
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
await fs.mkdir(path.dirname(params.targetPath), { recursive: true });
|
|
315
|
-
const templateContent = await fs.readFile(path.join(templatesDir(), params.templateName), "utf-8");
|
|
316
|
-
await fs.writeFile(params.targetPath, templateContent);
|
|
317
|
-
fixed = true;
|
|
225
|
+
async function invokeTalentTool(handlers, toolName, args) {
|
|
226
|
+
const handler = handlers.get(toolName);
|
|
227
|
+
if (!handler) {
|
|
228
|
+
throw new Error(`Talent tool '${toolName}' is unavailable`);
|
|
318
229
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
severity: "warning",
|
|
322
|
-
status: exists || fixed ? "pass" : "fail",
|
|
323
|
-
message: exists || fixed ? params.message : `${params.message.replace("exists", "is missing")}`,
|
|
324
|
-
path: params.targetPath,
|
|
325
|
-
fixable: true,
|
|
326
|
-
fixed,
|
|
327
|
-
};
|
|
230
|
+
const response = await handler(args);
|
|
231
|
+
return extractToolResponseData(response);
|
|
328
232
|
}
|
|
329
|
-
async function
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
233
|
+
async function registerCommand(args) {
|
|
234
|
+
const cardPath = getFlagString(args.flags, "agent-card");
|
|
235
|
+
if (!cardPath) {
|
|
236
|
+
throw new Error("Missing required --agent-card <path>");
|
|
333
237
|
}
|
|
334
|
-
|
|
335
|
-
|
|
238
|
+
const card = await readAgentCardFromPath(cardPath);
|
|
239
|
+
const coffeeShopUrl = getFlagString(args.flags, "coffeeshop-url") ?? DEFAULT_COFFEESHOP_URL;
|
|
240
|
+
const client = new CoffeeShopClient({ baseUrl: coffeeShopUrl });
|
|
241
|
+
const result = await client.register(card);
|
|
242
|
+
console.log(JSON.stringify(result, null, 2));
|
|
243
|
+
console.log("Save api_key now. It is only returned at registration time.");
|
|
244
|
+
}
|
|
245
|
+
async function discoverCommand(args) {
|
|
246
|
+
const requesterAgentId = getFlagString(args.flags, "requester-agent-id");
|
|
247
|
+
if (!requesterAgentId) {
|
|
248
|
+
throw new Error("Missing required --requester-agent-id <agent-id>");
|
|
336
249
|
}
|
|
250
|
+
const role = getFlagString(args.flags, "role");
|
|
251
|
+
const protocolVersion = getFlagString(args.flags, "protocol-version");
|
|
252
|
+
const limitRaw = getFlagString(args.flags, "limit");
|
|
253
|
+
const capabilitiesRaw = args.flags.capability;
|
|
254
|
+
const capabilities = Array.isArray(capabilitiesRaw)
|
|
255
|
+
? capabilitiesRaw
|
|
256
|
+
: typeof capabilitiesRaw === "string"
|
|
257
|
+
? [capabilitiesRaw]
|
|
258
|
+
: undefined;
|
|
259
|
+
const query = DiscoveryQuerySchema.parse({
|
|
260
|
+
requester_agent_id: requesterAgentId,
|
|
261
|
+
...(role ? { role } : {}),
|
|
262
|
+
...(protocolVersion ? { protocol_version: protocolVersion } : {}),
|
|
263
|
+
...(capabilities ? { capabilities_any: capabilities } : {}),
|
|
264
|
+
...(limitRaw ? { limit: Number.parseInt(limitRaw, 10) } : {}),
|
|
265
|
+
});
|
|
266
|
+
const coffeeShopUrl = getFlagString(args.flags, "coffeeshop-url") ?? DEFAULT_COFFEESHOP_URL;
|
|
267
|
+
const client = new CoffeeShopClient({ baseUrl: coffeeShopUrl });
|
|
268
|
+
const results = await client.discover(query);
|
|
269
|
+
console.log(JSON.stringify(results, null, 2));
|
|
337
270
|
}
|
|
338
|
-
async function
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
271
|
+
async function rotateKeyCommand(args) {
|
|
272
|
+
const agentId = getFlagString(args.flags, "agent-id");
|
|
273
|
+
if (!agentId) {
|
|
274
|
+
throw new Error("Missing required --agent-id <agent-id>");
|
|
342
275
|
}
|
|
343
|
-
|
|
344
|
-
|
|
276
|
+
const apiKey = getFlagString(args.flags, "api-key");
|
|
277
|
+
if (!apiKey) {
|
|
278
|
+
throw new Error("Missing required --api-key <api-key>");
|
|
345
279
|
}
|
|
280
|
+
const coffeeShopUrl = getFlagString(args.flags, "coffeeshop-url") ?? DEFAULT_COFFEESHOP_URL;
|
|
281
|
+
const client = new CoffeeShopClient({
|
|
282
|
+
baseUrl: coffeeShopUrl,
|
|
283
|
+
apiKey,
|
|
284
|
+
agentId,
|
|
285
|
+
});
|
|
286
|
+
const result = await client.rotateApiKey();
|
|
287
|
+
console.log(JSON.stringify(result, null, 2));
|
|
288
|
+
console.log("Save api_key now. It is only returned at rotation time.");
|
|
346
289
|
}
|
|
347
|
-
async function
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
290
|
+
async function introEventsCommand(args) {
|
|
291
|
+
const introId = getFlagString(args.flags, "intro-id");
|
|
292
|
+
if (!introId) {
|
|
293
|
+
throw new Error("Missing required --intro-id <intro-id>");
|
|
351
294
|
}
|
|
352
|
-
|
|
353
|
-
|
|
295
|
+
const apiKey = getFlagString(args.flags, "api-key");
|
|
296
|
+
if (!apiKey) {
|
|
297
|
+
throw new Error("Missing required --api-key <api-key>");
|
|
354
298
|
}
|
|
299
|
+
const coffeeShopUrl = getFlagString(args.flags, "coffeeshop-url") ?? DEFAULT_COFFEESHOP_URL;
|
|
300
|
+
const client = new CoffeeShopClient({
|
|
301
|
+
baseUrl: coffeeShopUrl,
|
|
302
|
+
apiKey,
|
|
303
|
+
});
|
|
304
|
+
const events = await client.listIntroEvents(introId);
|
|
305
|
+
console.log(JSON.stringify(events, null, 2));
|
|
355
306
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
307
|
+
function loadSharedSecretResolver(options) {
|
|
308
|
+
const fallbackSecret = process.env.ARTEMYS_SHARED_SECRET;
|
|
309
|
+
const fromMap = process.env.ARTEMYS_SHARED_SECRETS;
|
|
310
|
+
const parsedMap = fromMap ? JSON.parse(fromMap) : {};
|
|
311
|
+
return async (targetHint) => {
|
|
312
|
+
const mapped = parsedMap[targetHint];
|
|
313
|
+
if (mapped) {
|
|
314
|
+
return mapped;
|
|
315
|
+
}
|
|
316
|
+
if (fallbackSecret) {
|
|
317
|
+
return fallbackSecret;
|
|
318
|
+
}
|
|
319
|
+
if (options.coffeeShopClient) {
|
|
320
|
+
const resolved = await options.coffeeShopClient.resolveTransportSharedSecret(targetHint);
|
|
321
|
+
return resolved.value;
|
|
322
|
+
}
|
|
323
|
+
throw new Error(`No shared secret found for '${targetHint}'. Set ARTEMYS_SHARED_SECRETS/ARTEMYS_SHARED_SECRET or provide ARTEMYS_COFFEESHOP_API_KEY with accepted intro bootstrap.`);
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
async function mcpServerCommand(args) {
|
|
327
|
+
const cardPath = getFlagString(args.flags, "agent-card");
|
|
328
|
+
if (!cardPath) {
|
|
329
|
+
throw new Error("Missing required --agent-card <path>");
|
|
360
330
|
}
|
|
361
|
-
|
|
362
|
-
|
|
331
|
+
const transport = getFlagString(args.flags, "transport") === "sse" ? "sse" : "stdio";
|
|
332
|
+
const portRaw = getFlagString(args.flags, "port");
|
|
333
|
+
const port = portRaw ? Number.parseInt(portRaw, 10) : 3100;
|
|
334
|
+
const persist = getPersistOption(args.flags);
|
|
335
|
+
const agentCard = await readAgentCardFromPath(cardPath);
|
|
336
|
+
const { coffeeShopClient, transportClient, hasCoffeeShopApiKey } = buildNetworkDeps(args, agentCard);
|
|
337
|
+
const started = await startArtemysMcpServer({
|
|
338
|
+
agentCard,
|
|
339
|
+
coffeeShopClient,
|
|
340
|
+
transportClient,
|
|
341
|
+
transport,
|
|
342
|
+
port,
|
|
343
|
+
...(persist ? { persist } : {}),
|
|
344
|
+
enableIntroTools: hasCoffeeShopApiKey,
|
|
345
|
+
});
|
|
346
|
+
if (!hasCoffeeShopApiKey) {
|
|
347
|
+
console.error("Artemys MCP intro tools disabled (set ARTEMYS_COFFEESHOP_API_KEY to enable intro APIs)");
|
|
363
348
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (typeof value !== "string") {
|
|
367
|
-
return undefined;
|
|
349
|
+
if (transport === "sse") {
|
|
350
|
+
console.error(`Artemys MCP server listening on http://127.0.0.1:${port}/mcp`);
|
|
368
351
|
}
|
|
369
|
-
const
|
|
370
|
-
|
|
352
|
+
const shutdown = async () => {
|
|
353
|
+
await started.close();
|
|
354
|
+
process.exit(0);
|
|
355
|
+
};
|
|
356
|
+
process.on("SIGINT", shutdown);
|
|
357
|
+
process.on("SIGTERM", shutdown);
|
|
371
358
|
}
|
|
372
|
-
function
|
|
373
|
-
|
|
374
|
-
|
|
359
|
+
async function talentCommand(args) {
|
|
360
|
+
const subcommand = args.positionals[1] ?? "help";
|
|
361
|
+
if (subcommand === "help") {
|
|
362
|
+
printTalentHelp();
|
|
363
|
+
return;
|
|
375
364
|
}
|
|
376
|
-
|
|
377
|
-
|
|
365
|
+
const cardPath = getFlagString(args.flags, "agent-card");
|
|
366
|
+
if (!cardPath) {
|
|
367
|
+
throw new Error("Missing required --agent-card <path>");
|
|
378
368
|
}
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
369
|
+
const agentCard = await readAgentCardFromPath(cardPath);
|
|
370
|
+
const { coffeeShopClient, transportClient, hasCoffeeShopApiKey } = buildNetworkDeps(args, agentCard);
|
|
371
|
+
const state = buildTalentState(args.flags);
|
|
372
|
+
try {
|
|
373
|
+
const handlers = buildTalentToolHandlers({
|
|
374
|
+
coffeeShopClient,
|
|
375
|
+
transportClient,
|
|
376
|
+
tracker: state.tracker,
|
|
377
|
+
profileStore: state.profileStore,
|
|
378
|
+
agentCard,
|
|
379
|
+
introToolsEnabled: hasCoffeeShopApiKey,
|
|
380
|
+
});
|
|
381
|
+
if (subcommand === "search") {
|
|
382
|
+
const roleKeywords = getCsvFlagList(args.flags, "role-keywords");
|
|
383
|
+
const location = getFlagString(args.flags, "location");
|
|
384
|
+
const remoteOk = getFlagBoolean(args.flags, "remote-ok");
|
|
385
|
+
const seniority = getFlagString(args.flags, "seniority");
|
|
386
|
+
const limitRaw = getFlagString(args.flags, "limit");
|
|
387
|
+
const data = await invokeTalentTool(handlers, "search_opportunities", {
|
|
388
|
+
...(roleKeywords ? { role_keywords: roleKeywords } : {}),
|
|
389
|
+
...(location ? { location } : {}),
|
|
390
|
+
...(typeof remoteOk === "boolean" ? { remote_ok: remoteOk } : {}),
|
|
391
|
+
...(seniority ? { seniority } : {}),
|
|
392
|
+
...(limitRaw ? { limit: Number.parseInt(limitRaw, 10) } : {}),
|
|
393
|
+
});
|
|
394
|
+
console.log(JSON.stringify(data, null, 2));
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (subcommand === "apply") {
|
|
398
|
+
const targetAgentId = getFlagString(args.flags, "target-agent-id");
|
|
399
|
+
const targetEndpoint = getFlagString(args.flags, "target-endpoint");
|
|
400
|
+
const jobPostingRef = getFlagString(args.flags, "job-posting-ref");
|
|
401
|
+
if (!targetAgentId) {
|
|
402
|
+
throw new Error("Missing required --target-agent-id <agent-id>");
|
|
403
|
+
}
|
|
404
|
+
if (!targetEndpoint) {
|
|
405
|
+
throw new Error("Missing required --target-endpoint <url>");
|
|
406
|
+
}
|
|
407
|
+
if (!jobPostingRef) {
|
|
408
|
+
throw new Error("Missing required --job-posting-ref <job-ref>");
|
|
409
|
+
}
|
|
410
|
+
const matchReasoning = getFlagString(args.flags, "match-reasoning");
|
|
411
|
+
const data = await invokeTalentTool(handlers, "express_interest", {
|
|
412
|
+
target_agent_id: targetAgentId,
|
|
413
|
+
target_endpoint: targetEndpoint,
|
|
414
|
+
job_posting_ref: jobPostingRef,
|
|
415
|
+
...(matchReasoning ? { match_reasoning: matchReasoning } : {}),
|
|
416
|
+
});
|
|
417
|
+
console.log(JSON.stringify(data, null, 2));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (subcommand === "status") {
|
|
421
|
+
const statusFilter = getFlagString(args.flags, "status-filter");
|
|
422
|
+
const data = await invokeTalentTool(handlers, "check_conversations", {
|
|
423
|
+
...(statusFilter ? { status_filter: statusFilter } : {}),
|
|
424
|
+
});
|
|
425
|
+
console.log(JSON.stringify(data, null, 2));
|
|
426
|
+
return;
|
|
389
427
|
}
|
|
390
|
-
if (
|
|
391
|
-
|
|
428
|
+
if (subcommand === "profile") {
|
|
429
|
+
const profilePath = getFlagString(args.flags, "profile-file");
|
|
430
|
+
if (!profilePath) {
|
|
431
|
+
throw new Error("Missing required --profile-file <path>");
|
|
432
|
+
}
|
|
433
|
+
const profileRaw = await readFile(profilePath, "utf-8");
|
|
434
|
+
const parsedProfile = JSON.parse(profileRaw);
|
|
435
|
+
if (!parsedProfile || typeof parsedProfile !== "object" || Array.isArray(parsedProfile)) {
|
|
436
|
+
throw new Error("Profile file must contain a JSON object");
|
|
437
|
+
}
|
|
438
|
+
const syncAgentCard = getFlagBoolean(args.flags, "sync-agent-card");
|
|
439
|
+
const data = await invokeTalentTool(handlers, "update_profile", {
|
|
440
|
+
...parsedProfile,
|
|
441
|
+
...(typeof syncAgentCard === "boolean" ? { sync_agent_card: syncAgentCard } : {}),
|
|
442
|
+
});
|
|
443
|
+
console.log(JSON.stringify(data, null, 2));
|
|
444
|
+
return;
|
|
392
445
|
}
|
|
393
|
-
|
|
446
|
+
throw new Error(`Unknown talent subcommand: ${subcommand}`);
|
|
447
|
+
}
|
|
448
|
+
finally {
|
|
449
|
+
state.close();
|
|
394
450
|
}
|
|
395
451
|
}
|
|
396
|
-
async function
|
|
397
|
-
const
|
|
398
|
-
|
|
452
|
+
async function versionCommand() {
|
|
453
|
+
const packageJsonPath = new URL("../../package.json", import.meta.url);
|
|
454
|
+
const raw = await readFile(packageJsonPath, "utf-8");
|
|
455
|
+
const pkg = JSON.parse(raw);
|
|
456
|
+
console.log(pkg.version);
|
|
399
457
|
}
|
|
400
|
-
async function
|
|
401
|
-
const
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
458
|
+
export async function runCli(argv = process.argv.slice(2)) {
|
|
459
|
+
const args = parseArgs(argv);
|
|
460
|
+
const command = args.positionals[0] ?? "help";
|
|
461
|
+
if (command === "help") {
|
|
462
|
+
printHelp();
|
|
463
|
+
return;
|
|
406
464
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
465
|
+
if (command === "version") {
|
|
466
|
+
await versionCommand();
|
|
467
|
+
return;
|
|
410
468
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return await start();
|
|
423
|
-
case "help":
|
|
424
|
-
default:
|
|
425
|
-
return printHelp();
|
|
469
|
+
if (command === "register") {
|
|
470
|
+
await registerCommand(args);
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
if (command === "discover") {
|
|
474
|
+
await discoverCommand(args);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
if (command === "rotate-key") {
|
|
478
|
+
await rotateKeyCommand(args);
|
|
479
|
+
return;
|
|
426
480
|
}
|
|
481
|
+
if (command === "intro-events") {
|
|
482
|
+
await introEventsCommand(args);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if (command === "mcp-server") {
|
|
486
|
+
await mcpServerCommand(args);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (command === "talent") {
|
|
490
|
+
await talentCommand(args);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
throw new Error(`Unknown command: ${command}`);
|
|
494
|
+
}
|
|
495
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
496
|
+
runCli().catch((error) => {
|
|
497
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
498
|
+
process.exit(1);
|
|
499
|
+
});
|
|
427
500
|
}
|
|
428
|
-
main().catch((err) => {
|
|
429
|
-
console.error(`\nError: ${err instanceof Error ? err.message : String(err)}`);
|
|
430
|
-
if (process.env.DEBUG)
|
|
431
|
-
console.error(err);
|
|
432
|
-
process.exit(1);
|
|
433
|
-
});
|
|
434
501
|
//# sourceMappingURL=index.js.map
|