revert: remove Collective Wisdom V1 (#94266)
Reverts the in-tree org skill-marketplace: hermes_wisdom package, three model tools, CLI/gateway/desktop/dashboard/Telegram/Slack surfaces. Later non-Wisdom work on shared files (guest onboarding i18n, dashboard startup schema, Slack adapter, tui_gateway) is kept; Wisdom-only call sites and config were stripped from those files.
This commit is contained in:
@@ -1,108 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Shared environment resolver for the Collective Wisdom demo launchers.
|
||||
#
|
||||
# This file is sourced by scripts/wisdom-demo-env.sh and by the repo-local
|
||||
# `hermes` shim. Keep it side-effect free until
|
||||
# wisdom_demo_export_environment is called.
|
||||
|
||||
wisdom_demo_repo_root() {
|
||||
if [ -n "${HERMES_WISDOM_REPO:-}" ] \
|
||||
&& [ -f "${HERMES_WISDOM_REPO}/hermes_cli/main.py" ]; then
|
||||
(cd "${HERMES_WISDOM_REPO}" && pwd)
|
||||
return
|
||||
fi
|
||||
|
||||
local helper_dir
|
||||
helper_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
(cd "${helper_dir}/../.." && pwd)
|
||||
}
|
||||
|
||||
wisdom_demo_python_is_ready() {
|
||||
"$1" -c 'import dotenv, pydantic, requests, yaml' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
wisdom_demo_pick_python() {
|
||||
local repo_root="$1"
|
||||
local candidate
|
||||
|
||||
if [ -n "${HERMES_WISDOM_PYTHON:-}" ]; then
|
||||
if [ ! -x "${HERMES_WISDOM_PYTHON}" ]; then
|
||||
echo "error: HERMES_WISDOM_PYTHON is not executable: ${HERMES_WISDOM_PYTHON}" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! wisdom_demo_python_is_ready "${HERMES_WISDOM_PYTHON}"; then
|
||||
echo "error: HERMES_WISDOM_PYTHON lacks Hermes runtime dependencies: ${HERMES_WISDOM_PYTHON}" >&2
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' "${HERMES_WISDOM_PYTHON}"
|
||||
return
|
||||
fi
|
||||
|
||||
for candidate in \
|
||||
"${repo_root}/.venv/bin/python" \
|
||||
"${repo_root}/venv/bin/python" \
|
||||
"${HERMES_PYTHON:-}" \
|
||||
"${HERMES_HOME:-}/hermes-agent/venv/bin/python" \
|
||||
"${HOME:-}/.hermes/hermes-agent/venv/bin/python"
|
||||
do
|
||||
if [ -n "${candidate}" ] \
|
||||
&& [ -x "${candidate}" ] \
|
||||
&& wisdom_demo_python_is_ready "${candidate}"; then
|
||||
printf '%s\n' "${candidate}"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
candidate="$(command -v python3 2>/dev/null || true)"
|
||||
if [ -n "${candidate}" ] \
|
||||
&& [ -x "${candidate}" ] \
|
||||
&& wisdom_demo_python_is_ready "${candidate}"; then
|
||||
printf '%s\n' "${candidate}"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "error: no Python interpreter is available for the Wisdom worktree" >&2
|
||||
echo "hint: set HERMES_WISDOM_PYTHON to a Hermes development venv interpreter" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
wisdom_demo_prepend_colon_path() {
|
||||
local value="$1"
|
||||
local current="$2"
|
||||
|
||||
case ":${current}:" in
|
||||
*":${value}:"*) printf '%s\n' "${current}" ;;
|
||||
*)
|
||||
if [ -n "${current}" ]; then
|
||||
printf '%s:%s\n' "${value}" "${current}"
|
||||
else
|
||||
printf '%s\n' "${value}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
wisdom_demo_export_environment() {
|
||||
local repo_root
|
||||
local python
|
||||
local demo_bin
|
||||
|
||||
repo_root="$(wisdom_demo_repo_root)" || return 1
|
||||
python="$(wisdom_demo_pick_python "${repo_root}")" || return 1
|
||||
demo_bin="${repo_root}/scripts/wisdom-demo-bin"
|
||||
|
||||
export HERMES_WISDOM_REPO="${repo_root}"
|
||||
export HERMES_WISDOM_PYTHON="${python}"
|
||||
export HERMES_PYTHON="${python}"
|
||||
export HERMES_DESKTOP_PYTHON="${python}"
|
||||
export HERMES_DESKTOP_HERMES_ROOT="${repo_root}"
|
||||
export PYTHONPATH
|
||||
PYTHONPATH="$(wisdom_demo_prepend_colon_path "${repo_root}" "${PYTHONPATH:-}")"
|
||||
export PATH
|
||||
PATH="$(wisdom_demo_prepend_colon_path "${demo_bin}" "${PATH:-}")"
|
||||
|
||||
# Bash caches command lookups. Clear an older global `hermes` resolution so
|
||||
# the newly-prepended worktree shim takes effect immediately when sourced.
|
||||
hash -r 2>/dev/null || true
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fail CI when pinned Wisdom artifacts or canonical algorithms drift."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from hermes_wisdom.contract import (
|
||||
CONTRACT_PIN,
|
||||
ContentFile,
|
||||
author_description_hash,
|
||||
canonical_content_manifest,
|
||||
derive_content_hash,
|
||||
sanitize_author_description,
|
||||
sha256_address,
|
||||
)
|
||||
|
||||
|
||||
CONTRACTS = ROOT / "hermes_wisdom" / "contracts"
|
||||
|
||||
|
||||
def digest(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--gateway-dir", type=Path, help="Verify artifacts against the pinned Gateway git commit")
|
||||
args = parser.parse_args()
|
||||
openapi = CONTRACTS / "gateway-openapi.json"
|
||||
schema = CONTRACTS / "skill-manifest.schema.v1.json"
|
||||
vectors_path = CONTRACTS / "canonical-hash-vectors.v1.json"
|
||||
assert digest(openapi) == CONTRACT_PIN.openapi_sha256
|
||||
assert digest(schema) == CONTRACT_PIN.manifest_schema_sha256
|
||||
assert digest(vectors_path) == CONTRACT_PIN.canonical_vectors_sha256
|
||||
if args.gateway_dir is not None:
|
||||
sources = {
|
||||
openapi: "openapi.json",
|
||||
schema: "docs/design/collective-wisdom/contracts/skill-manifest.schema.v1.json",
|
||||
vectors_path: "docs/design/collective-wisdom/contracts/canonical-hash-vectors.v1.json",
|
||||
}
|
||||
for artifact, source in sources.items():
|
||||
pinned = subprocess.run(
|
||||
["git", "-C", str(args.gateway_dir), "show", f"{CONTRACT_PIN.gateway_commit}:{source}"],
|
||||
check=True, capture_output=True,
|
||||
).stdout
|
||||
assert artifact.read_bytes() == pinned, f"Pinned Gateway source differs: {source}"
|
||||
vectors = json.loads(vectors_path.read_text(encoding="utf-8"))
|
||||
for vector in [vectors, *vectors["content_hash_cases"]]:
|
||||
files: list[ContentFile] = []
|
||||
for item in vector["files"]:
|
||||
body = base64.b64decode(item["content_base64"], validate=True)
|
||||
assert body.decode("utf-8") == item["content_utf8"]
|
||||
assert sha256_address(body) == item["hash"]
|
||||
files.append(
|
||||
ContentFile(path=item["path"], mode=item["mode"], hash=item["hash"])
|
||||
)
|
||||
assert (
|
||||
canonical_content_manifest(files).decode("utf-8")
|
||||
== vector["canonical_content_manifest_utf8"]
|
||||
)
|
||||
assert derive_content_hash(files) == vector["content_hash"]
|
||||
assert (
|
||||
next(
|
||||
item["hash"]
|
||||
for item in vectors["files"]
|
||||
if item["path"] == "skill.manifest.json"
|
||||
)
|
||||
== vectors["package_manifest_hash"]
|
||||
)
|
||||
canonical = sanitize_author_description(vectors["author_description_input"])
|
||||
assert canonical == vectors["canonical_author_description"]
|
||||
assert author_description_hash(canonical) == vectors["author_description_hash"]
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"ok": True,
|
||||
"gateway_commit": CONTRACT_PIN.gateway_commit,
|
||||
"openapi_sha256": digest(openapi),
|
||||
"manifest_schema_sha256": digest(schema),
|
||||
"canonical_vectors_sha256": digest(vectors_path),
|
||||
},
|
||||
sort_keys=True,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Repo-local Hermes shim used by scripts/wisdom-demo-env.sh.
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=scripts/lib/wisdom-demo-env.sh
|
||||
source "${SCRIPT_DIR}/../lib/wisdom-demo-env.sh"
|
||||
wisdom_demo_export_environment
|
||||
|
||||
exec "${HERMES_WISDOM_PYTHON}" -m hermes_cli.main "$@"
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pin every Hermes surface in this shell to the current source worktree.
|
||||
#
|
||||
# Source it to configure the current shell:
|
||||
# source scripts/wisdom-demo-env.sh
|
||||
#
|
||||
# Execute it to open a configured interactive subshell:
|
||||
# scripts/wisdom-demo-env.sh
|
||||
#
|
||||
# Or run one command without changing the caller's environment:
|
||||
# scripts/wisdom-demo-env.sh -- hermes wisdom status
|
||||
|
||||
_wisdom_demo_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=scripts/lib/wisdom-demo-env.sh
|
||||
source "${_wisdom_demo_script_dir}/lib/wisdom-demo-env.sh"
|
||||
unset _wisdom_demo_script_dir
|
||||
if ! wisdom_demo_export_environment; then
|
||||
if [ "${BASH_SOURCE[0]}" != "$0" ]; then
|
||||
return 1
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${HERMES_WISDOM_QUIET:-0}" != "1" ]; then
|
||||
echo "Collective Wisdom demo environment"
|
||||
echo " source: ${HERMES_WISDOM_REPO}"
|
||||
echo " python: ${HERMES_WISDOM_PYTHON}"
|
||||
if [ -n "${HERMES_HOME:-}" ]; then
|
||||
echo " profile home: ${HERMES_HOME}"
|
||||
else
|
||||
echo " profile home: default Hermes profile"
|
||||
fi
|
||||
echo " hermes: $(command -v hermes)"
|
||||
fi
|
||||
|
||||
unset -f \
|
||||
wisdom_demo_repo_root \
|
||||
wisdom_demo_python_is_ready \
|
||||
wisdom_demo_pick_python \
|
||||
wisdom_demo_prepend_colon_path \
|
||||
wisdom_demo_export_environment 2>/dev/null || true
|
||||
|
||||
if [ "${BASH_SOURCE[0]}" != "$0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--" ]; then
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
echo "Opening a demo shell. Exit it to return to your previous environment."
|
||||
exec "${SHELL:-/bin/bash}" -i
|
||||
@@ -1,730 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Launch the local Collective Wisdom demo as one coordinated, foreground stack.
|
||||
#
|
||||
# The supervisor keeps Portal, Gateway, the Hermes messaging gateway, Dashboard,
|
||||
# and Desktop on the default Hermes profile while isolating local demo
|
||||
# credentials and logs. Press Ctrl-C to stop application processes; database
|
||||
# and object-store containers are intentionally left running so demo state
|
||||
# survives.
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PORTAL_APP="${WISDOM_PORTAL_APP:-${ROOT}/../Nous/hermes-portal-wisdom/apps/nous-account-service}"
|
||||
GATEWAY_REPO="${WISDOM_GATEWAY_REPO:-${ROOT}/../Nous/gateway-gateway}"
|
||||
DEMO_HOME="${WISDOM_DEMO_HOME:-${HOME}/.hermes/wisdom-local-demo}"
|
||||
AGENT_HOME="${WISDOM_AGENT_HOME:-${HERMES_HOME:-${HOME}/.hermes}}"
|
||||
STATE_DIR="${WISDOM_DEMO_STATE_DIR:-${DEMO_HOME}/demo-stack}"
|
||||
PUBLISHER_HOME="${WISDOM_PUBLISHER_HOME:-${DEMO_HOME}/publisher}"
|
||||
PUBLISHER_METADATA="${STATE_DIR}/publisher-fixture.json"
|
||||
PORTAL_URL="${WISDOM_PORTAL_URL:-http://127.0.0.1:3111}"
|
||||
GATEWAY_URL="${WISDOM_GATEWAY_URL:-http://127.0.0.1:8787}"
|
||||
DASHBOARD_UI_PORT="${WISDOM_DASHBOARD_UI_PORT:-5173}"
|
||||
TEAM_ORG_ID="${WISDOM_TEAM_ORG_ID:-nas_organisation:wisdom-local}"
|
||||
TEAM_ORG_SLUG="${WISDOM_TEAM_ORG_SLUG:-wisdom-local}"
|
||||
PRIVY_DID="${WISDOM_PRIVY_DID:-did:privy:user-9399fb3c}"
|
||||
MINIO_CONTAINER="${WISDOM_MINIO_CONTAINER:-codex-wisdom-minio}"
|
||||
MINIO_BUCKET="${WISDOM_MINIO_BUCKET:-wisdom}"
|
||||
MINIO_ENDPOINT="${WISDOM_MINIO_ENDPOINT:-http://127.0.0.1:20900}"
|
||||
PG_URL="postgresql://postgres:password@127.0.0.1:5436"
|
||||
|
||||
declare -a CHILD_PIDS=()
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/wisdom-demo-stack.sh [up|login|status|publisher-setup|publisher-v1|publisher-v2]
|
||||
|
||||
up Start the complete local demo in this terminal (default).
|
||||
login Refresh the foreground Portal browser's local demo session.
|
||||
status Show the expected listener state without changing anything.
|
||||
publisher-setup Create or refresh the isolated second-member fixture.
|
||||
publisher-v1 Publish a unique v1 skill as the second team member.
|
||||
publisher-v2 Publish v2 of the fixture skill after recipient install.
|
||||
|
||||
Useful overrides:
|
||||
WISDOM_PORTAL_APP, WISDOM_GATEWAY_REPO, HERMES_HOME,
|
||||
WISDOM_AGENT_HOME, WISDOM_DEMO_HOME, WISDOM_DASHBOARD_UI_PORT,
|
||||
WISDOM_PRIVY_DID, WISDOM_TEAM_ORG_ID, WISDOM_TEAM_ORG_SLUG
|
||||
EOF
|
||||
}
|
||||
|
||||
port_pid() {
|
||||
lsof -nP -iTCP:"$1" -sTCP:LISTEN -t 2>/dev/null | head -1
|
||||
}
|
||||
|
||||
messaging_gateway_pid() {
|
||||
(
|
||||
export HERMES_HOME="${AGENT_HOME}"
|
||||
export HERMES_SHARED_AUTH_DIR="${DEMO_HOME}/shared"
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
"${HERMES_WISDOM_PYTHON}" - "${AGENT_HOME}" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
from gateway.control_socket import identify_gateway
|
||||
|
||||
identity = identify_gateway(Path(sys.argv[1]), timeout=0.25)
|
||||
if identity and identity.get("pid"):
|
||||
print(identity["pid"])
|
||||
PY
|
||||
)
|
||||
}
|
||||
|
||||
status() {
|
||||
local port label pid messaging_pid
|
||||
while read -r port label; do
|
||||
pid="$(port_pid "${port}" || true)"
|
||||
if [[ -n "${pid}" ]]; then
|
||||
printf '%-18s up (:%s, pid %s)\n' "${label}" "${port}" "${pid}"
|
||||
else
|
||||
printf '%-18s down (:%s)\n' "${label}" "${port}"
|
||||
fi
|
||||
done <<EOF
|
||||
3111 Portal
|
||||
3112 Privy mock
|
||||
3114 LiteLLM mock
|
||||
8787 Gateway
|
||||
9119 Dashboard API
|
||||
${DASHBOARD_UI_PORT} Dashboard UI
|
||||
5174 Desktop renderer
|
||||
EOF
|
||||
|
||||
messaging_pid="$(messaging_gateway_pid 2>/dev/null || true)"
|
||||
if [[ -n "${messaging_pid}" ]]; then
|
||||
printf '%-18s up (pid %s)\n' "Messaging gateway" "${messaging_pid}"
|
||||
else
|
||||
printf '%-18s down\n' "Messaging gateway"
|
||||
fi
|
||||
}
|
||||
|
||||
require_directory() {
|
||||
[[ -d "$1" ]] || {
|
||||
echo "error: required checkout not found: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
require_free_port() {
|
||||
local port="$1" label="$2" pid
|
||||
pid="$(port_pid "${port}" || true)"
|
||||
[[ -z "${pid}" ]] || {
|
||||
echo "error: ${label} port ${port} is already in use by pid ${pid}" >&2
|
||||
echo "hint: stop the existing demo stack, then run this command again" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
wait_for_port() {
|
||||
local port="$1" label="$2"
|
||||
for _ in $(seq 1 120); do
|
||||
if nc -z 127.0.0.1 "${port}" 2>/dev/null; then
|
||||
echo "ready: ${label} (:${port})"
|
||||
return 0
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
echo "error: ${label} did not bind port ${port}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
wait_for_http() {
|
||||
local url="$1" expected="$2" label="$3" status_code
|
||||
for _ in $(seq 1 90); do
|
||||
status_code="$(curl -sS -o /dev/null -w '%{http_code}' "${url}" 2>/dev/null || true)"
|
||||
if [[ "${status_code}" == "${expected}" ]]; then
|
||||
echo "ready: ${label} (HTTP ${status_code})"
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "error: ${label} did not return HTTP ${expected}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
wait_for_messaging_gateway() {
|
||||
local pid
|
||||
for _ in $(seq 1 120); do
|
||||
pid="$(messaging_gateway_pid 2>/dev/null || true)"
|
||||
if [[ -n "${pid}" ]]; then
|
||||
echo "ready: Hermes messaging gateway (pid ${pid})"
|
||||
return 0
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
echo "error: Hermes messaging gateway control socket did not become ready" >&2
|
||||
tail -n 40 "${STATE_DIR}/messaging-gateway.log" >&2 || true
|
||||
return 1
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local name="$1" cwd="$2"
|
||||
shift 2
|
||||
echo "starting: ${name} (log: ${STATE_DIR}/${name}.log)"
|
||||
(
|
||||
cd "${cwd}"
|
||||
exec "$@"
|
||||
) >"${STATE_DIR}/${name}.log" 2>&1 &
|
||||
CHILD_PIDS+=("$!")
|
||||
}
|
||||
|
||||
kill_tree() {
|
||||
local pid="$1" child
|
||||
while read -r child; do
|
||||
[[ -n "${child}" ]] && kill_tree "${child}"
|
||||
done < <(pgrep -P "${pid}" 2>/dev/null || true)
|
||||
kill -TERM "${pid}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
trap - EXIT INT TERM
|
||||
echo
|
||||
echo "stopping Collective Wisdom demo applications..."
|
||||
local pid
|
||||
for pid in "${CHILD_PIDS[@]:-}"; do
|
||||
[[ -n "${pid}" ]] && kill_tree "${pid}"
|
||||
done
|
||||
echo "application processes stopped; Docker data was preserved"
|
||||
}
|
||||
|
||||
start_portal_process() {
|
||||
local name="$1" command="$2"
|
||||
echo "starting: ${name} (log: ${STATE_DIR}/${name}.log)"
|
||||
(
|
||||
cd "${PORTAL_APP}"
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source e2e/browser/env.source
|
||||
set +a
|
||||
export HERMES_WISDOM_LOCAL=1
|
||||
export HERMES_SYNC_PLANE_URL="${GATEWAY_URL}"
|
||||
ulimit -n 65536
|
||||
exec bash -lc "${command}"
|
||||
) >"${STATE_DIR}/${name}.log" 2>&1 &
|
||||
CHILD_PIDS+=("$!")
|
||||
}
|
||||
|
||||
start_agent_process() {
|
||||
local name="$1" cwd="$2"
|
||||
shift 2
|
||||
echo "starting: ${name} (log: ${STATE_DIR}/${name}.log)"
|
||||
(
|
||||
cd "${cwd}"
|
||||
export HERMES_HOME="${AGENT_HOME}"
|
||||
export HERMES_SHARED_AUTH_DIR="${DEMO_HOME}/shared"
|
||||
export GATEWAY_URL
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
exec "$@"
|
||||
) >"${STATE_DIR}/${name}.log" 2>&1 &
|
||||
CHILD_PIDS+=("$!")
|
||||
}
|
||||
|
||||
start_messaging_gateway_process() {
|
||||
local name="messaging-gateway"
|
||||
echo "starting: Hermes messaging gateway (log: ${STATE_DIR}/${name}.log)"
|
||||
(
|
||||
cd "${ROOT}"
|
||||
export HERMES_HOME="${AGENT_HOME}"
|
||||
export HERMES_SHARED_AUTH_DIR="${DEMO_HOME}/shared"
|
||||
export GATEWAY_URL
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
|
||||
while true; do
|
||||
set +e
|
||||
hermes gateway run --replace --external-supervisor -v
|
||||
gateway_exit=$?
|
||||
set -e
|
||||
|
||||
case "${gateway_exit}" in
|
||||
0)
|
||||
echo "Hermes messaging gateway stopped cleanly"
|
||||
exit 0
|
||||
;;
|
||||
75)
|
||||
echo "Hermes messaging gateway requested restart; relaunching"
|
||||
;;
|
||||
78)
|
||||
echo "Hermes messaging gateway has a fatal configuration error; not restarting" >&2
|
||||
exit 78
|
||||
;;
|
||||
*)
|
||||
echo "Hermes messaging gateway exited with status ${gateway_exit}; retrying in 1 second" >&2
|
||||
sleep 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
) >"${STATE_DIR}/${name}.log" 2>&1 &
|
||||
CHILD_PIDS+=("$!")
|
||||
}
|
||||
|
||||
authenticate_demo() {
|
||||
local auth_record="${STATE_DIR}/portal-login.json"
|
||||
local -a relogin_args=(
|
||||
--privy-did "${PRIVY_DID}"
|
||||
--org-id "${TEAM_ORG_ID}"
|
||||
)
|
||||
|
||||
# The Portal helper needs --hermes-home only for the first device-code
|
||||
# bootstrap. On repeat launches an existing shared credential is imported
|
||||
# without a device code, which the helper correctly refuses to treat as a
|
||||
# fresh authorization. The Wisdom setup below refreshes and revalidates the
|
||||
# existing team-scoped credential instead.
|
||||
if [[ ! -s "${DEMO_HOME}/shared/nous_auth.json" ]]; then
|
||||
relogin_args+=(--hermes-home "${DEMO_HOME}")
|
||||
fi
|
||||
|
||||
export HERMES_HOME="${AGENT_HOME}"
|
||||
export HERMES_SHARED_AUTH_DIR="${DEMO_HOME}/shared"
|
||||
export GATEWAY_URL
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
|
||||
(
|
||||
cd "${PORTAL_APP}"
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source e2e/browser/env.source
|
||||
set +a
|
||||
pnpm exec tsx scripts/relogin-account.ts "${relogin_args[@]}"
|
||||
) >"${auth_record}"
|
||||
chmod 600 "${auth_record}"
|
||||
|
||||
hermes config set sync.base_url "${GATEWAY_URL}" --force >/dev/null
|
||||
hermes config set wisdom.portal_url "${PORTAL_URL}" --force >/dev/null
|
||||
local setup_ok=""
|
||||
for _ in $(seq 1 30); do
|
||||
if hermes wisdom setup --accept-disclosure --json \
|
||||
>"${STATE_DIR}/wisdom-setup.json" 2>"${STATE_DIR}/wisdom-setup.log"; then
|
||||
setup_ok=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [[ -z "${setup_ok}" ]]; then
|
||||
echo "error: Hermes Wisdom setup did not become ready" >&2
|
||||
tail -n 20 "${STATE_DIR}/wisdom-setup.log" >&2 || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
open_portal_login "${auth_record}"
|
||||
}
|
||||
|
||||
open_portal_login() {
|
||||
local auth_record="$1"
|
||||
local handoff_pid
|
||||
|
||||
AUTH_FILE="${auth_record}" \
|
||||
PORTAL_REDIRECT="${PORTAL_URL}/orgs/${TEAM_ORG_SLUG}/wisdom" \
|
||||
node -e '
|
||||
const http = require("node:http");
|
||||
const fs = require("node:fs");
|
||||
const record = JSON.parse(fs.readFileSync(process.env.AUTH_FILE, "utf8"));
|
||||
const close = () => {
|
||||
server.close();
|
||||
server.closeAllConnections();
|
||||
};
|
||||
const timeout = setTimeout(() => {
|
||||
close();
|
||||
}, 30000);
|
||||
const server = http.createServer((_request, response) => {
|
||||
clearTimeout(timeout);
|
||||
response.statusCode = 302;
|
||||
response.setHeader("Connection", "close");
|
||||
for (const cookie of record.cookies) {
|
||||
response.appendHeader(
|
||||
"Set-Cookie",
|
||||
`${cookie.name}=${cookie.value}; Path=/; SameSite=Lax`,
|
||||
);
|
||||
}
|
||||
response.setHeader("Location", process.env.PORTAL_REDIRECT);
|
||||
response.end();
|
||||
setTimeout(close, 1000);
|
||||
});
|
||||
server.listen(3120, "127.0.0.1");
|
||||
' >"${STATE_DIR}/browser-login.log" 2>&1 &
|
||||
handoff_pid="$!"
|
||||
CHILD_PIDS+=("${handoff_pid}")
|
||||
wait_for_port 3120 "browser login handoff"
|
||||
open "http://127.0.0.1:3120/login"
|
||||
wait "${handoff_pid}"
|
||||
}
|
||||
|
||||
login() {
|
||||
local auth_record="${STATE_DIR}/portal-login.json"
|
||||
local -a relogin_args=(
|
||||
--privy-did "${PRIVY_DID}"
|
||||
--org-id "${TEAM_ORG_ID}"
|
||||
)
|
||||
|
||||
require_directory "${PORTAL_APP}"
|
||||
mkdir -p "${STATE_DIR}"
|
||||
require_free_port 3120 "browser-login"
|
||||
[[ -n "$(port_pid 3111 || true)" ]] || {
|
||||
echo "error: Portal is not running on ${PORTAL_URL}" >&2
|
||||
echo "hint: start the demo with scripts/wisdom-demo-stack.sh up" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
(
|
||||
cd "${PORTAL_APP}"
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source e2e/browser/env.source
|
||||
set +a
|
||||
pnpm exec tsx scripts/relogin-account.ts "${relogin_args[@]}"
|
||||
) >"${auth_record}"
|
||||
chmod 600 "${auth_record}"
|
||||
|
||||
open_portal_login "${auth_record}"
|
||||
echo "Portal demo login refreshed for ${TEAM_ORG_SLUG}"
|
||||
}
|
||||
|
||||
require_publisher_demo_stack() {
|
||||
local port
|
||||
[[ "${TEAM_ORG_ID}" == "nas_organisation:wisdom-local" ]] || {
|
||||
echo "error: publisher fixture only supports nas_organisation:wisdom-local" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${TEAM_ORG_SLUG}" == "wisdom-local" ]] || {
|
||||
echo "error: publisher fixture only supports the wisdom-local slug" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${PORTAL_URL}" =~ ^http://(127\.0\.0\.1|localhost)(:[0-9]+)?$ ]] || {
|
||||
echo "error: publisher fixture requires a loopback HTTP Portal" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${GATEWAY_URL}" =~ ^http://(127\.0\.0\.1|localhost)(:[0-9]+)?$ ]] || {
|
||||
echo "error: publisher fixture requires a loopback HTTP Gateway" >&2
|
||||
exit 1
|
||||
}
|
||||
command -v jq >/dev/null || {
|
||||
echo "error: publisher fixture requires jq" >&2
|
||||
exit 1
|
||||
}
|
||||
for port in 3111 3112 8787; do
|
||||
[[ -n "$(port_pid "${port}" || true)" ]] || {
|
||||
echo "error: local demo service is not listening on port ${port}" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
publisher_portal_script() {
|
||||
(
|
||||
cd "${PORTAL_APP}"
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source e2e/browser/env.source
|
||||
set +a
|
||||
export HERMES_WISDOM_LOCAL=1
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# Ensure helpers which spawn `hermes` use this worktree and a complete
|
||||
# runtime, not whichever global CLI happens to be first on PATH.
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
pnpm exec tsx "$@"
|
||||
)
|
||||
}
|
||||
|
||||
publisher_hermes() {
|
||||
(
|
||||
export HERMES_HOME="${PUBLISHER_HOME}"
|
||||
export HERMES_SHARED_AUTH_DIR="${PUBLISHER_HOME}/shared"
|
||||
export GATEWAY_URL
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
hermes "$@"
|
||||
)
|
||||
}
|
||||
|
||||
publisher_setup() {
|
||||
require_directory "${PORTAL_APP}"
|
||||
require_publisher_demo_stack
|
||||
mkdir -p "${STATE_DIR}" "${PUBLISHER_HOME}/shared"
|
||||
|
||||
local account_record fixture_record publisher_did publisher_user recipient_user
|
||||
account_record="$(mktemp "${STATE_DIR}/publisher-account.XXXXXX")"
|
||||
fixture_record="$(mktemp "${STATE_DIR}/publisher-membership.XXXXXX")"
|
||||
trap "rm -f -- '${account_record}' '${fixture_record}'" RETURN
|
||||
|
||||
if [[ -s "${PUBLISHER_METADATA}" ]]; then
|
||||
publisher_did="$(jq -er '.publisherPrivyDid' "${PUBLISHER_METADATA}")"
|
||||
else
|
||||
publisher_portal_script scripts/mint-account.ts \
|
||||
--email "wisdom-publisher-$(date +%s)@example.com" \
|
||||
--name "Wisdom Demo Publisher" >"${account_record}"
|
||||
chmod 600 "${account_record}"
|
||||
publisher_did="$(jq -er '.privyDid' "${account_record}")"
|
||||
fi
|
||||
|
||||
publisher_portal_script scripts/prepare-wisdom-demo-member.ts \
|
||||
--publisher-privy-did "${publisher_did}" \
|
||||
--recipient-privy-did "${PRIVY_DID}" \
|
||||
--org-id "${TEAM_ORG_ID}" >"${fixture_record}"
|
||||
publisher_user="$(jq -er '.publisherUserId' "${fixture_record}")"
|
||||
recipient_user="$(jq -er '.recipientUserId' "${fixture_record}")"
|
||||
[[ "${publisher_user}" != "${recipient_user}" ]] || {
|
||||
echo "error: publisher and recipient unexpectedly resolve to the same user" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "$(jq -er '.organizationId' "${fixture_record}")" == "${TEAM_ORG_ID}" ]] || {
|
||||
echo "error: publisher fixture resolved the wrong organization" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
jq -s '.[0] * .[1]' \
|
||||
<(if [[ -s "${PUBLISHER_METADATA}" ]]; then cat "${PUBLISHER_METADATA}"; else echo '{}'; fi) \
|
||||
"${fixture_record}" >"${PUBLISHER_METADATA}.tmp"
|
||||
mv "${PUBLISHER_METADATA}.tmp" "${PUBLISHER_METADATA}"
|
||||
chmod 600 "${PUBLISHER_METADATA}"
|
||||
|
||||
if [[ ! -s "${PUBLISHER_HOME}/shared/nous_auth.json" ]]; then
|
||||
publisher_portal_script scripts/relogin-account.ts \
|
||||
--privy-did "${publisher_did}" \
|
||||
--org-id "${TEAM_ORG_ID}" \
|
||||
--hermes-home "${PUBLISHER_HOME}" >"${account_record}"
|
||||
fi
|
||||
|
||||
publisher_hermes config set sync.base_url "${GATEWAY_URL}" --force >/dev/null
|
||||
publisher_hermes config set wisdom.portal_url "${PORTAL_URL}" --force >/dev/null
|
||||
publisher_hermes config set auxiliary.background_review.provider codex --force >/dev/null
|
||||
publisher_hermes config set auxiliary.background_review.model gpt-5.6-sol --force >/dev/null
|
||||
publisher_hermes wisdom setup --accept-disclosure --json \
|
||||
>"${STATE_DIR}/publisher-wisdom-setup.json"
|
||||
|
||||
echo "Publisher fixture ready"
|
||||
echo " publisher: ${publisher_user}"
|
||||
echo " recipient: ${recipient_user}"
|
||||
echo " org: ${TEAM_ORG_ID}"
|
||||
echo " home: ${PUBLISHER_HOME}"
|
||||
}
|
||||
|
||||
publisher_write_skill() {
|
||||
local slug="$1" version="$2" skill_dir="${PUBLISHER_HOME}/skills/${1}"
|
||||
mkdir -p "${skill_dir}"
|
||||
printf '%s\n' \
|
||||
'---' \
|
||||
"name: ${slug}" \
|
||||
"description: Verify cross-surface Collective Wisdom delivery for version ${version}." \
|
||||
'metadata:' \
|
||||
' hermes:' \
|
||||
' editorial_name: Cross-Surface Notification Demo' \
|
||||
" editorial_description: A local team skill used to verify install and update notifications (v${version})." \
|
||||
'---' \
|
||||
'# Cross-Surface Notification Demo' \
|
||||
'' \
|
||||
"When asked to run the Wisdom notification demo, report that version ${version} is active." \
|
||||
>"${skill_dir}/SKILL.md"
|
||||
}
|
||||
|
||||
recipient_approve_wisdom_proposal() {
|
||||
local proposal_n="$1"
|
||||
(
|
||||
export HERMES_HOME="${AGENT_HOME}"
|
||||
export HERMES_SHARED_AUTH_DIR="${DEMO_HOME}/shared"
|
||||
export HERMES_WISDOM_QUIET=1
|
||||
# shellcheck disable=SC1091
|
||||
source "${ROOT}/scripts/wisdom-demo-env.sh"
|
||||
"${HERMES_WISDOM_PYTHON}" - \
|
||||
"${DEMO_HOME}/shared/nous_auth.json" \
|
||||
"${GATEWAY_URL}" \
|
||||
"${proposal_n}" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
|
||||
auth_path, gateway_url, proposal_n = sys.argv[1:]
|
||||
token = json.loads(Path(auth_path).read_text(encoding="utf-8"))["access_token"]
|
||||
response = requests.post(
|
||||
f"{gateway_url.rstrip('/')}/v1/sync/org/proposals/{proposal_n}/approve",
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
json={},
|
||||
timeout=30,
|
||||
)
|
||||
if response.status_code != 200:
|
||||
raise SystemExit(
|
||||
f"local recipient moderation failed ({response.status_code}): "
|
||||
f"{response.text[:500]}"
|
||||
)
|
||||
print(response.text)
|
||||
PY
|
||||
)
|
||||
}
|
||||
|
||||
publisher_publish_current() {
|
||||
local slug="$1" version="$2" submitted draft_id approved state proposal_n moderated
|
||||
publisher_hermes wisdom suggest "${slug}" \
|
||||
--description "A local team skill used to verify install and update notifications (v${version})." \
|
||||
--json >"${STATE_DIR}/publisher-v${version}-prepared.json"
|
||||
submitted="$(publisher_hermes wisdom suggest "${slug}" \
|
||||
--description "A local team skill used to verify install and update notifications (v${version})." \
|
||||
--system-specification-json '{"hermes":{"minimum_version":"0.20.5"}}' \
|
||||
--json)"
|
||||
printf '%s\n' "${submitted}" >"${STATE_DIR}/publisher-v${version}-submitted.json"
|
||||
draft_id="$(jq -er '.draft.id' <<<"${submitted}")"
|
||||
publisher_hermes wisdom review "${draft_id}" --acknowledge --json \
|
||||
>"${STATE_DIR}/publisher-v${version}-review.json"
|
||||
approved="$(publisher_hermes wisdom approve "${draft_id}" --json)"
|
||||
printf '%s\n' "${approved}" >"${STATE_DIR}/publisher-v${version}-approval.json"
|
||||
state="$(jq -r '.publication.state // .state // empty' <<<"${approved}")"
|
||||
if [[ "${state}" == "pending_moderation" ]]; then
|
||||
proposal_n="$(jq -er '.publication.proposal_id' <<<"${approved}")"
|
||||
moderated="$(recipient_approve_wisdom_proposal "${proposal_n}")"
|
||||
printf '%s\n' "${moderated}" \
|
||||
>"${STATE_DIR}/publisher-v${version}-moderation.json"
|
||||
state="$(jq -r '.state // empty' <<<"${moderated}")"
|
||||
fi
|
||||
[[ "${state}" == "published" || "${state}" == "approved" ]] || {
|
||||
echo "error: publisher v${version} ended in '${state:-unknown}', expected published" >&2
|
||||
exit 1
|
||||
}
|
||||
jq --arg slug "${slug}" --argjson version "${version}" \
|
||||
'.skillSlug=$slug | .publishedVersion=$version' \
|
||||
"${PUBLISHER_METADATA}" >"${PUBLISHER_METADATA}.tmp"
|
||||
mv "${PUBLISHER_METADATA}.tmp" "${PUBLISHER_METADATA}"
|
||||
chmod 600 "${PUBLISHER_METADATA}"
|
||||
echo "Published ${slug} v${version} as a different wisdom-local member"
|
||||
}
|
||||
|
||||
publisher_v1() {
|
||||
publisher_setup >/dev/null
|
||||
local slug
|
||||
slug="${WISDOM_PUBLISHER_SKILL_SLUG:-org-notification-demo-$(date +%Y%m%d%H%M%S)}"
|
||||
publisher_write_skill "${slug}" 1
|
||||
publisher_publish_current "${slug}" 1
|
||||
}
|
||||
|
||||
publisher_v2() {
|
||||
publisher_setup >/dev/null
|
||||
[[ -s "${PUBLISHER_METADATA}" ]] || {
|
||||
echo "error: run publisher-v1 first" >&2
|
||||
exit 1
|
||||
}
|
||||
local slug published_version
|
||||
slug="$(jq -er '.skillSlug' "${PUBLISHER_METADATA}")"
|
||||
published_version="$(jq -er '.publishedVersion' "${PUBLISHER_METADATA}")"
|
||||
[[ "${published_version}" -eq 1 ]] || {
|
||||
echo "error: publisher-v2 requires a completed v1 fixture" >&2
|
||||
exit 1
|
||||
}
|
||||
publisher_write_skill "${slug}" 2
|
||||
publisher_publish_current "${slug}" 2
|
||||
}
|
||||
|
||||
up() {
|
||||
require_directory "${PORTAL_APP}"
|
||||
require_directory "${GATEWAY_REPO}"
|
||||
require_directory "${ROOT}/apps/desktop"
|
||||
mkdir -p "${STATE_DIR}" "${DEMO_HOME}/shared"
|
||||
|
||||
for spec in \
|
||||
"3111 Portal" \
|
||||
"3112 Privy-mock" \
|
||||
"3114 LiteLLM-mock" \
|
||||
"8787 Gateway" \
|
||||
"9119 Dashboard-API" \
|
||||
"${DASHBOARD_UI_PORT} Dashboard-UI" \
|
||||
"5174 Desktop-renderer" \
|
||||
"3120 browser-login"; do
|
||||
# shellcheck disable=SC2086
|
||||
require_free_port ${spec}
|
||||
done
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
docker compose \
|
||||
-p codex-wisdom-portal \
|
||||
-f "${PORTAL_APP}/docker-compose.yaml" \
|
||||
up -d postgres redis serverless-redis-http >/dev/null
|
||||
if docker inspect "${MINIO_CONTAINER}" >/dev/null 2>&1; then
|
||||
docker start "${MINIO_CONTAINER}" >/dev/null
|
||||
else
|
||||
echo "error: ${MINIO_CONTAINER} is missing; create the UAT MinIO container first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start_portal_process "privy-mock" "exec npx tsx e2e/mocks/privy/main.ts"
|
||||
start_portal_process "litellm-mock" "exec npx tsx e2e/mocks/litellm/main.ts"
|
||||
wait_for_port 3112 "Privy mock"
|
||||
wait_for_port 3114 "LiteLLM mock"
|
||||
|
||||
local minio_user minio_password
|
||||
minio_user="$(docker inspect "${MINIO_CONTAINER}" --format '{{range .Config.Env}}{{println .}}{{end}}' | sed -n 's/^MINIO_ROOT_USER=//p')"
|
||||
minio_password="$(docker inspect "${MINIO_CONTAINER}" --format '{{range .Config.Env}}{{println .}}{{end}}' | sed -n 's/^MINIO_ROOT_PASSWORD=//p')"
|
||||
start_service "gateway" "${GATEWAY_REPO}" env \
|
||||
PORT=8787 \
|
||||
DATABASE_URL="${PG_URL}/gateway_gateway" \
|
||||
NOUS_PORTAL_URL="${PORTAL_URL}" \
|
||||
SYNC_ENABLED=1 \
|
||||
SYNC_OBJECT_STORE_REGION=us-east-1 \
|
||||
SYNC_OBJECT_STORE_BUCKET="${MINIO_BUCKET}" \
|
||||
SYNC_OBJECT_STORE_ACCESS_KEY_ID="${minio_user}" \
|
||||
SYNC_OBJECT_STORE_SECRET_ACCESS_KEY="${minio_password}" \
|
||||
SYNC_OBJECT_STORE_ENDPOINT="${MINIO_ENDPOINT}" \
|
||||
WISDOM_REGISTRY=1 \
|
||||
npm run dev
|
||||
wait_for_port 8787 "Gateway"
|
||||
wait_for_http "${GATEWAY_URL}/healthz" 200 "Gateway health"
|
||||
|
||||
start_portal_process \
|
||||
"portal" \
|
||||
"exec pnpm exec next dev --turbo --hostname 127.0.0.1 --port 3111"
|
||||
wait_for_port 3111 "Portal"
|
||||
wait_for_http "${PORTAL_URL}/api/oauth/account" 401 "Portal OAuth issuer"
|
||||
|
||||
authenticate_demo
|
||||
|
||||
start_messaging_gateway_process
|
||||
wait_for_messaging_gateway
|
||||
|
||||
start_agent_process \
|
||||
"dashboard-api" "${ROOT}" \
|
||||
hermes dashboard --host 127.0.0.1 --port 9119 --no-open --isolated --skip-build
|
||||
wait_for_port 9119 "Dashboard API"
|
||||
|
||||
start_service "dashboard-ui" "${ROOT}/web" env \
|
||||
HERMES_DASHBOARD_URL=http://127.0.0.1:9119 \
|
||||
npm run dev -- --host 127.0.0.1 --port "${DASHBOARD_UI_PORT}" --strictPort
|
||||
wait_for_port "${DASHBOARD_UI_PORT}" "Dashboard UI"
|
||||
|
||||
start_agent_process "desktop" "${ROOT}" npm run dev --workspace apps/desktop
|
||||
wait_for_port 5174 "Desktop renderer"
|
||||
open "http://127.0.0.1:${DASHBOARD_UI_PORT}/skills"
|
||||
|
||||
echo
|
||||
echo "Collective Wisdom demo is ready"
|
||||
echo " Portal: ${PORTAL_URL}/orgs/${TEAM_ORG_SLUG}/wisdom"
|
||||
echo " Management:${PORTAL_URL}/orgs/${TEAM_ORG_SLUG}/wisdom/admin"
|
||||
echo " Dashboard: http://127.0.0.1:${DASHBOARD_UI_PORT}/skills"
|
||||
echo " Messaging: supervised (log: ${STATE_DIR}/messaging-gateway.log)"
|
||||
echo " CLI: HERMES_HOME=${AGENT_HOME} HERMES_SHARED_AUTH_DIR=${DEMO_HOME}/shared ${ROOT}/scripts/wisdom-demo-env.sh -- hermes wisdom status"
|
||||
echo
|
||||
echo "Keep this terminal open. Press Ctrl-C to stop application processes."
|
||||
wait
|
||||
}
|
||||
|
||||
main() {
|
||||
case "${1:-up}" in
|
||||
up) up ;;
|
||||
login) login ;;
|
||||
status) status ;;
|
||||
publisher-setup) publisher_setup ;;
|
||||
publisher-v1) publisher_v1 ;;
|
||||
publisher-v2) publisher_v2 ;;
|
||||
-h|--help|help) usage ;;
|
||||
*) usage >&2; exit 2 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user