@dotdrelle/wiki-manager 0.14.20 → 0.15.25
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/.env.example +28 -0
- package/README.md +137 -11
- package/agents.docker-compose.yml +41 -0
- package/docker-compose.yml +11 -1
- package/mcp.endpoints.example.json +3 -3
- package/package.json +1 -2
- package/src/agent/graph.js +92 -12
- package/src/agent/graph.test.js +108 -6
- package/src/cli/runtimeStartup.test.js +14 -0
- package/src/cli/wiki-manager.js +190 -29
- package/src/cli/wiki-manager.test.js +91 -0
- package/src/commands/slash.js +58 -0
- package/src/commands/slash.test.js +18 -0
- package/src/core/activity.js +1 -1
- package/src/core/activity.test.js +5 -0
- package/src/core/buildInfo.json +2 -2
- package/src/core/compose.js +7 -1
- package/src/core/dockerCompose.test.js +27 -3
- package/src/core/env.js +16 -3
- package/src/core/env.test.js +8 -3
- package/src/core/mcp.js +21 -8
- package/src/core/mcp.test.js +55 -0
- package/src/core/wikiSetup.js +26 -2
- package/src/core/wikiWorkspace.test.js +25 -0
- package/src/orchestrator/dispatcher.js +42 -17
- package/src/orchestrator/dispatcher.test.js +127 -0
- package/src/runtime/client.js +23 -0
- package/src/runtime/runner.js +3 -1
- package/src/shell/LeftPane.tsx +20 -1
- package/src/shell/repl.js +134 -36
- package/src/shell/repl.test.js +187 -15
- package/src/shell/useAgent.ts +8 -12
- package/tsconfig.json +2 -1
- package/wiki-workspace +110 -18
- package/agents.docker-compose.mailer.example.yml +0 -36
package/wiki-workspace
CHANGED
|
@@ -222,17 +222,20 @@ agents_compose() {
|
|
|
222
222
|
|
|
223
223
|
_agents_dc() {
|
|
224
224
|
local cacert_args=()
|
|
225
|
+
local profile_args=()
|
|
226
|
+
connectors_enabled && profile_args+=(--profile connectors)
|
|
225
227
|
WORKSPACES_ROOT="$workspaces_root" AGENTS_DATA_DIR="$agents_data_dir" \
|
|
226
228
|
read_lines_into_array cacert_args cacert_compose_args "$agents_compose_file" "agents.cacert.compose.yml"
|
|
227
|
-
# User-owned override: optional external agents
|
|
229
|
+
# User-owned override: optional external agents live in a
|
|
228
230
|
# file the user maintains NEXT TO the .env — never generated, never
|
|
229
231
|
# overwritten by package updates.
|
|
230
232
|
local override_args=()
|
|
231
233
|
local user_override="$MANAGER_STATE_DIR/agents.docker-compose.override.yml"
|
|
232
234
|
[[ -f "$user_override" ]] && override_args+=(-f "$user_override")
|
|
233
235
|
WORKSPACES_ROOT="$workspaces_root" AGENTS_DATA_DIR="$agents_data_dir" \
|
|
236
|
+
COMPOSE_PROFILES= \
|
|
234
237
|
docker compose --project-directory "$DEFAULT_MANAGER_DIR" \
|
|
235
|
-
${compose_env_args[@]+"${compose_env_args[@]}"} -f "$agents_compose_file" ${override_args[@]+"${override_args[@]}"} ${cacert_args[@]+"${cacert_args[@]}"} -p wiki-agents "$@"
|
|
238
|
+
${compose_env_args[@]+"${compose_env_args[@]}"} -f "$agents_compose_file" ${override_args[@]+"${override_args[@]}"} ${cacert_args[@]+"${cacert_args[@]}"} ${profile_args[@]+"${profile_args[@]}"} -p wiki-agents "$@"
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
case "$subcommand" in
|
|
@@ -250,6 +253,7 @@ agents_compose() {
|
|
|
250
253
|
compose_env_args=()
|
|
251
254
|
[[ -f "$MANAGER_ENV_FILE" ]] && compose_env_args+=(--env-file "$MANAGER_ENV_FILE")
|
|
252
255
|
mkdir -p "$agents_data_dir/cme" "$agents_data_dir/documents/input" "$agents_data_dir/documents/output" "$agents_data_dir/documents/uploads"
|
|
256
|
+
connectors_enabled && mkdir -p "$agents_data_dir/connectors"
|
|
253
257
|
mkdir -p "$workspaces_root"
|
|
254
258
|
$do_pull && _agents_dc pull
|
|
255
259
|
local up_args=(up -d)
|
|
@@ -260,8 +264,10 @@ agents_compose() {
|
|
|
260
264
|
printf 'Workspaces root: %s\n' "$workspaces_root"
|
|
261
265
|
printf 'Agents data: %s\n' "$agents_data_dir"
|
|
262
266
|
[[ -z "$CACERT_PATH" ]] || printf 'CA cert: %s -> /wiki-manager-ca.pem\n' "$CACERT_PATH"
|
|
263
|
-
printf 'Agents: cme=:%s documents=:%s
|
|
267
|
+
printf 'Agents: cme=:%s documents=:%s' \
|
|
264
268
|
"${CME_MCP_PORT:-3336}" "${DOCUMENTS_MCP_PORT:-3337}"
|
|
269
|
+
connectors_enabled && printf ' connectors=:%s' "${CONNECTORS_MCP_PORT:-3338}"
|
|
270
|
+
printf '\n'
|
|
265
271
|
[[ ! -f "$MANAGER_STATE_DIR/agents.docker-compose.override.yml" ]] || printf 'User override: agents.docker-compose.override.yml included\n'
|
|
266
272
|
;;
|
|
267
273
|
down)
|
|
@@ -409,7 +415,7 @@ ensure_runtime_node() {
|
|
|
409
415
|
}
|
|
410
416
|
|
|
411
417
|
ensure_agent_tokens() {
|
|
412
|
-
#
|
|
418
|
+
# External agents authenticate with tokens
|
|
413
419
|
# from the manager .env — generate any missing one, exactly like the
|
|
414
420
|
# workspace and runtime tokens are generated. Leaving them empty made a
|
|
415
421
|
# fresh install start agents nobody could talk to.
|
|
@@ -423,6 +429,34 @@ ensure_agent_tokens() {
|
|
|
423
429
|
printf 'Generated %s in %s\n' "$key" "$MANAGER_ENV_FILE"
|
|
424
430
|
fi
|
|
425
431
|
done
|
|
432
|
+
if connectors_enabled; then
|
|
433
|
+
for key in CONNECTORS_MCP_AUTH_TOKEN OAUTH_STATE_SECRET OAUTH_START_TOKEN; do
|
|
434
|
+
token="$(env_value "$MANAGER_ENV_FILE" "$key" "")"
|
|
435
|
+
if [[ -z "$token" ]]; then
|
|
436
|
+
token="$(generate_token)"
|
|
437
|
+
mkdir -p "$(dirname "$MANAGER_ENV_FILE")"
|
|
438
|
+
set_env_value "$MANAGER_ENV_FILE" "$key" "$token"
|
|
439
|
+
printf 'Generated %s in %s\n' "$key" "$MANAGER_ENV_FILE"
|
|
440
|
+
fi
|
|
441
|
+
done
|
|
442
|
+
local callback_url connectors_port
|
|
443
|
+
callback_url="$(env_value "$MANAGER_ENV_FILE" GOOGLE_OAUTH_CALLBACK_URL "")"
|
|
444
|
+
if [[ -z "$callback_url" ]]; then
|
|
445
|
+
connectors_port="$(env_value "$MANAGER_ENV_FILE" CONNECTORS_MCP_PORT "${CONNECTORS_MCP_PORT:-3338}")"
|
|
446
|
+
callback_url="http://127.0.0.1:${connectors_port}/oauth/google/callback"
|
|
447
|
+
set_env_value "$MANAGER_ENV_FILE" GOOGLE_OAUTH_CALLBACK_URL "$callback_url"
|
|
448
|
+
printf 'Configured local GOOGLE_OAUTH_CALLBACK_URL in %s\n' "$MANAGER_ENV_FILE"
|
|
449
|
+
fi
|
|
450
|
+
fi
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
connectors_enabled() {
|
|
454
|
+
local enabled
|
|
455
|
+
enabled="$(env_value "$MANAGER_ENV_FILE" CONNECTORS_ENABLED "${CONNECTORS_ENABLED:-false}")"
|
|
456
|
+
case "$enabled" in
|
|
457
|
+
1|[Tt][Rr][Uu][Ee]|[Yy][Ee][Ss]|[Oo][Nn]) return 0 ;;
|
|
458
|
+
*) return 1 ;;
|
|
459
|
+
esac
|
|
426
460
|
}
|
|
427
461
|
|
|
428
462
|
ensure_endpoints_file() {
|
|
@@ -433,6 +467,44 @@ ensure_endpoints_file() {
|
|
|
433
467
|
cp "$ROOT_DIR/mcp.endpoints.example.json" "$MANAGER_ENDPOINTS_FILE"
|
|
434
468
|
printf 'Created %s from packaged example\n' "$MANAGER_ENDPOINTS_FILE"
|
|
435
469
|
fi
|
|
470
|
+
[[ -f "$MANAGER_ENDPOINTS_FILE" ]] || return
|
|
471
|
+
local connector_state=false
|
|
472
|
+
connectors_enabled && connector_state=true
|
|
473
|
+
node - "$MANAGER_ENDPOINTS_FILE" "$connector_state" <<'NODE'
|
|
474
|
+
import fs from 'node:fs';
|
|
475
|
+
|
|
476
|
+
const [, , filePath, enabled] = process.argv;
|
|
477
|
+
const config = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
478
|
+
config.mcpServers ??= {};
|
|
479
|
+
config.chatAccess ??= { maxToolIterations: 8, servers: {} };
|
|
480
|
+
config.chatAccess.servers ??= {};
|
|
481
|
+
if (enabled === 'true') {
|
|
482
|
+
config.mcpServers.connectors ??= {
|
|
483
|
+
url: 'http://host.docker.internal:${CONNECTORS_MCP_PORT:-3338}/mcp/',
|
|
484
|
+
headers: {
|
|
485
|
+
Authorization: 'Bearer ${CONNECTORS_MCP_AUTH_TOKEN}',
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
config.chatAccess.servers.connectors ??= {};
|
|
489
|
+
const connectorAccess = config.chatAccess.servers.connectors;
|
|
490
|
+
// One shape for every server: a single `allow` list. The legacy
|
|
491
|
+
// `allowActions` split is folded back in and removed, so a file written by
|
|
492
|
+
// an older manager converges to the common shape on the next `agents up`.
|
|
493
|
+
connectorAccess.allow = [
|
|
494
|
+
...new Set([
|
|
495
|
+
...(Array.isArray(connectorAccess.allow) ? connectorAccess.allow : []),
|
|
496
|
+
...(Array.isArray(connectorAccess.allowActions) ? connectorAccess.allowActions : []),
|
|
497
|
+
'connectors_google_status',
|
|
498
|
+
'connectors_google_oauth_start',
|
|
499
|
+
]),
|
|
500
|
+
];
|
|
501
|
+
delete connectorAccess.allowActions;
|
|
502
|
+
} else {
|
|
503
|
+
delete config.mcpServers.connectors;
|
|
504
|
+
delete config.chatAccess.servers.connectors;
|
|
505
|
+
}
|
|
506
|
+
fs.writeFileSync(filePath, `${JSON.stringify(config, null, 2)}\n`);
|
|
507
|
+
NODE
|
|
436
508
|
}
|
|
437
509
|
|
|
438
510
|
ensure_manager_runtime_token() {
|
|
@@ -476,8 +548,12 @@ runtime_pid_matches() {
|
|
|
476
548
|
[[ "$command" == *"/bin/wiki-manager.js runtime"* || "$command" == *" bin/wiki-manager.js runtime"* ]]
|
|
477
549
|
}
|
|
478
550
|
|
|
551
|
+
runtime_port() {
|
|
552
|
+
env_value "$MANAGER_ENV_FILE" WIKI_MANAGER_RUNTIME_PORT "${WIKI_MANAGER_RUNTIME_PORT:-7788}"
|
|
553
|
+
}
|
|
554
|
+
|
|
479
555
|
runtime_health_url() {
|
|
480
|
-
printf 'http://127.0.0.1:%s/health\n' "$
|
|
556
|
+
printf 'http://127.0.0.1:%s/health\n' "$(runtime_port)"
|
|
481
557
|
}
|
|
482
558
|
|
|
483
559
|
runtime_health_check() {
|
|
@@ -497,11 +573,24 @@ runtime_health_check() {
|
|
|
497
573
|
RUNTIME_URL="$url" RUNTIME_TOKEN="$token" "$node_bin" --input-type=module -e "const h=process.env.RUNTIME_TOKEN?{Authorization:'Bearer '+process.env.RUNTIME_TOKEN}:{}; const r=await fetch(process.env.RUNTIME_URL,{headers:h}); process.exit(r.ok?0:1);"
|
|
498
574
|
}
|
|
499
575
|
|
|
576
|
+
wait_for_runtime_health() {
|
|
577
|
+
local attempts="${1:-60}"
|
|
578
|
+
local i=0
|
|
579
|
+
while (( i < attempts )); do
|
|
580
|
+
runtime_health_check && return 0
|
|
581
|
+
runtime_pid_running || return 1
|
|
582
|
+
sleep 0.25
|
|
583
|
+
(( i++ )) || true
|
|
584
|
+
done
|
|
585
|
+
return 1
|
|
586
|
+
}
|
|
587
|
+
|
|
500
588
|
runtime_command() {
|
|
501
589
|
local subcommand="$1"
|
|
502
590
|
shift
|
|
503
591
|
local host="${WIKI_MANAGER_RUNTIME_HOST:-0.0.0.0}"
|
|
504
|
-
local port
|
|
592
|
+
local port
|
|
593
|
+
port="$(runtime_port)"
|
|
505
594
|
local pid_file log_file node_bin token
|
|
506
595
|
pid_file="$(runtime_pid_file)"
|
|
507
596
|
log_file="$(runtime_log_file)"
|
|
@@ -519,17 +608,21 @@ runtime_command() {
|
|
|
519
608
|
return
|
|
520
609
|
fi
|
|
521
610
|
if runtime_pid_running; then
|
|
522
|
-
printf 'agent-runtime process
|
|
523
|
-
|
|
611
|
+
printf 'Waiting for agent-runtime process (pid %s)...\n' "$(cat "$pid_file")"
|
|
612
|
+
else
|
|
613
|
+
WIKI_WORKSPACES_DIR="$WORKSPACES_DIR" \
|
|
614
|
+
WIKI_MANAGER_ENV_FILE="$MANAGER_ENV_FILE" \
|
|
615
|
+
WIKI_MANAGER_STATE_DIR="$MANAGER_RUNTIME_DIR" \
|
|
616
|
+
WIKI_MANAGER_RUNTIME_TOKEN="$token" \
|
|
617
|
+
nohup "$node_bin" "$ROOT_DIR/bin/wiki-manager.js" runtime --host "$host" --port "$port" --state-dir "$MANAGER_RUNTIME_DIR" > "$log_file" 2>&1 &
|
|
618
|
+
printf '%s\n' "$!" > "$pid_file"
|
|
619
|
+
fi
|
|
620
|
+
if ! wait_for_runtime_health; then
|
|
621
|
+
printf 'agent-runtime failed to become healthy at %s\n' "$(runtime_health_url)" >&2
|
|
622
|
+
[[ ! -f "$log_file" ]] || tail -20 "$log_file" >&2
|
|
623
|
+
return 1
|
|
524
624
|
fi
|
|
525
|
-
|
|
526
|
-
WIKI_MANAGER_ENV_FILE="$MANAGER_ENV_FILE" \
|
|
527
|
-
WIKI_MANAGER_STATE_DIR="$MANAGER_RUNTIME_DIR" \
|
|
528
|
-
WIKI_MANAGER_RUNTIME_TOKEN="$token" \
|
|
529
|
-
nohup "$node_bin" "$ROOT_DIR/bin/wiki-manager.js" runtime --host "$host" --port "$port" --state-dir "$MANAGER_RUNTIME_DIR" > "$log_file" 2>&1 &
|
|
530
|
-
printf '%s\n' "$!" > "$pid_file"
|
|
531
|
-
sleep 0.5
|
|
532
|
-
printf 'agent-runtime started on http://127.0.0.1:%s (pid %s)\n' "$port" "$(cat "$pid_file")"
|
|
625
|
+
printf 'agent-runtime healthy on http://127.0.0.1:%s (pid %s)\n' "$port" "$(cat "$pid_file")"
|
|
533
626
|
printf 'state: %s\nlog: %s\n' "$MANAGER_RUNTIME_DIR" "$log_file"
|
|
534
627
|
;;
|
|
535
628
|
down|stop)
|
|
@@ -819,8 +912,7 @@ cacert_compose_args() {
|
|
|
819
912
|
done <<< "$services"
|
|
820
913
|
} > "$tmp_override"
|
|
821
914
|
# Always replace generated state: package updates may add/remove services,
|
|
822
|
-
# and retaining an older override creates invalid phantom services
|
|
823
|
-
# example a removed optional mailer with no image in the current base file).
|
|
915
|
+
# and retaining an older override creates invalid phantom services.
|
|
824
916
|
mv "$tmp_override" "$override_path"
|
|
825
917
|
printf '%s\n' -f "$override_path"
|
|
826
918
|
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# agents.docker-compose.mailer.example.yml — optional MailerSend agent
|
|
2
|
-
#
|
|
3
|
-
# The mailer agent is NOT part of the default delivery: it is an external
|
|
4
|
-
# MCP connector operated at the user's charge. To enable it:
|
|
5
|
-
#
|
|
6
|
-
# 1. Copy this file NEXT TO YOUR .env (the directory where you run
|
|
7
|
-
# wiki-manager) under the name: agents.docker-compose.override.yml
|
|
8
|
-
# That file is yours — wiki-manager never generates or overwrites it,
|
|
9
|
-
# and `wiki-workspace agents up` includes it automatically when present.
|
|
10
|
-
# 2. Add to your .env:
|
|
11
|
-
# MAILER_MCP_AUTH_TOKEN=$(openssl rand -hex 32)
|
|
12
|
-
# MAILERSEND_API_KEY=...
|
|
13
|
-
# MAILERSEND_FROM_EMAIL=...
|
|
14
|
-
# 3. Declare the endpoint in your mcp.endpoints.json:
|
|
15
|
-
# "mailer": {
|
|
16
|
-
# "url": "http://host.docker.internal:${MAILER_MCP_PORT:-3335}/mcp/",
|
|
17
|
-
# "headers": { "Authorization": "Bearer ${MAILER_MCP_AUTH_TOKEN}" }
|
|
18
|
-
# }
|
|
19
|
-
#
|
|
20
|
-
services:
|
|
21
|
-
mailer:
|
|
22
|
-
image: dotdrelle/agent-mailer-api:latest
|
|
23
|
-
user: "${UID:-1000}:${GID:-1000}"
|
|
24
|
-
ports:
|
|
25
|
-
- "${MAILER_MCP_PORT:-3335}:8080"
|
|
26
|
-
environment:
|
|
27
|
-
- MAILERSEND_API_KEY=${MAILERSEND_API_KEY:-}
|
|
28
|
-
- MAILERSEND_FROM_EMAIL=${MAILERSEND_FROM_EMAIL:-no-reply@example.com}
|
|
29
|
-
- MAILERSEND_FROM_NAME=${MAILERSEND_FROM_NAME:-Mailer Agent}
|
|
30
|
-
- MAILERSEND_USER_AGENT=${MAILERSEND_USER_AGENT:-curl/8.7.1}
|
|
31
|
-
- MAILERSEND_VERIFY_SSL=${MAILERSEND_VERIFY_SSL:-true}
|
|
32
|
-
- MAILERSEND_CA_CERT=${MAILERSEND_CA_CERT:-}
|
|
33
|
-
- MAILER_REQUIRE_CONFIRMATION=${MAILER_REQUIRE_CONFIRMATION:-true}
|
|
34
|
-
- MAILER_DRY_RUN=${MAILER_DRY_RUN:-false}
|
|
35
|
-
- MCP_AUTH_TOKEN=${MAILER_MCP_AUTH_TOKEN:-}
|
|
36
|
-
restart: unless-stopped
|