Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to `@useorgx/openclaw-plugin` are documented in this file.

## 0.7.35 - 2026-05-18

### OpenClaw 2026.5 Compatibility
- Declared startup activation so the OrgX dashboard and local HTTP routes load when the gateway starts.
- Added the runtime tool ownership contract required by newer OpenClaw plugin loading.
- Redirected legacy `/orgx/chat` deep links into the live dashboard while preserving query parameters.
- Updated local deploy/dev scripts to target OpenClaw's managed npm plugin install before the legacy extension path.

## 0.7.33 - 2026-04-13

### Release Management
Expand Down
42 changes: 41 additions & 1 deletion openclaw.plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "orgx",
"name": "OrgX for OpenClaw",
"version": "0.7.34",
"version": "0.7.35",
"description": "Persistent organizational memory and coordinated execution for OpenClaw agents",
"entry": "./dist/index.js",
"author": "OrgX Team",
Expand All @@ -13,13 +13,53 @@
"engines": {
"node": ">=18.0.0"
},
"activation": {
"onStartup": true
},
"skills": ["skills"],
"capabilities": {
"tools": true,
"services": true,
"cli": true,
"http": true
},
"contracts": {
"tools": [
"orgx_status",
"orgx_sentinel_catalog",
"orgx_sync",
"orgx_get_morning_brief",
"orgx_query_org_memory",
"orgx_recommend_next_action",
"orgx_delegation_preflight",
"orgx_run_action",
"orgx_checkpoints_list",
"orgx_checkpoint_restore",
"orgx_spawn_check",
"orgx_quality_score",
"orgx_proof_status",
"orgx_verify_completion",
"orgx_record_outcome",
"orgx_get_outcome_attribution",
"orgx_create_entity",
"orgx_update_entity",
"orgx_reassign_stream",
"orgx_reassign_streams",
"orgx_list_entities",
"orgx_emit_activity",
"orgx_apply_changeset",
"orgx_report_progress",
"orgx_request_decision",
"orgx_register_artifact",
"orgx_agent_sessions",
"orgx_resume_agent_session",
"orgx_clear_agent_session",
"list_agent_configs",
"get_agent_config",
"update_agent_config",
"update_stream_progress"
]
},
"configSchema": {
"type": "object",
"properties": {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@useorgx/openclaw-plugin",
"version": "0.7.34",
"version": "0.7.35",
"description": "Persistent organizational memory and coordination for OpenClaw agents",
"type": "module",
"main": "./dist/index.js",
Expand Down
46 changes: 31 additions & 15 deletions scripts/deploy-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
EXTENSIONS_DIR="${HOME}/.openclaw/extensions/openclaw-plugin"
LEGACY_EXTENSIONS_DIR="${HOME}/.openclaw/extensions/openclaw-plugin"
NPM_PLUGIN_DIR="${HOME}/.openclaw/npm/node_modules/@useorgx/openclaw-plugin"
CONFIG_FILE="${HOME}/.openclaw/openclaw.json"
LAUNCH_AGENT="gui/$(id -u)/ai.openclaw.gateway"

Expand Down Expand Up @@ -60,24 +61,36 @@ if ! $LOCAL_ONLY; then
echo "Published @useorgx/openclaw-plugin@${VERSION}"
fi

# --- Install to extensions dir ---
echo "Installing to ${EXTENSIONS_DIR}..."
if [ -d "$EXTENSIONS_DIR" ]; then
find "$EXTENSIONS_DIR" -mindepth 1 -delete 2>/dev/null || true
INSTALL_DIRS=()
if [ -d "$NPM_PLUGIN_DIR" ]; then
INSTALL_DIRS+=("$NPM_PLUGIN_DIR")
else
INSTALL_DIRS+=("$LEGACY_EXTENSIONS_DIR")
fi
mkdir -p "$EXTENSIONS_DIR"

if $LOCAL_ONLY; then
cp -R dist openclaw.plugin.json package.json LICENSE README.md "$EXTENSIONS_DIR/"
[ -d dashboard/dist ] && mkdir -p "$EXTENSIONS_DIR/dashboard" && cp -R dashboard/dist "$EXTENSIONS_DIR/dashboard/"
[ -d skills ] && cp -R skills "$EXTENSIONS_DIR/"
echo "Installing runtime dependencies for local extension..."
(cd "$EXTENSIONS_DIR" && npm install --omit=dev)
else
if ! $LOCAL_ONLY; then
TMPDIR=$(mktemp -d)
(cd "$TMPDIR" && npm pack "@useorgx/openclaw-plugin@${VERSION}" --silent && tar xzf *.tgz && cp -R package/* "$EXTENSIONS_DIR/")
(cd "$TMPDIR" && npm pack "@useorgx/openclaw-plugin@${VERSION}" --silent && tar xzf *.tgz)
fi

for INSTALL_DIR in "${INSTALL_DIRS[@]}"; do
echo "Installing to ${INSTALL_DIR}..."
if [ -d "$INSTALL_DIR" ]; then
find "$INSTALL_DIR" -mindepth 1 -delete 2>/dev/null || true
fi
mkdir -p "$INSTALL_DIR"

if $LOCAL_ONLY; then
cp -R dist openclaw.plugin.json package.json LICENSE README.md "$INSTALL_DIR/"
[ -d dashboard/dist ] && mkdir -p "$INSTALL_DIR/dashboard" && cp -R dashboard/dist "$INSTALL_DIR/dashboard/"
[ -d skills ] && cp -R skills "$INSTALL_DIR/"
echo "Installing runtime dependencies for local plugin at ${INSTALL_DIR}..."
(cd "$INSTALL_DIR" && npm install --omit=dev)
else
cp -R "$TMPDIR"/package/* "$INSTALL_DIR/"
fi
done

# --- Update config version ---
if [ -f "$CONFIG_FILE" ]; then
sed -i '' "s/\"version\": \"[0-9]*\.[0-9]*\.[0-9]*\"/\"version\": \"${VERSION}\"/" "$CONFIG_FILE"
Expand All @@ -89,5 +102,8 @@ launchctl kickstart -k "$LAUNCH_AGENT" 2>/dev/null || echo "Gateway not running

echo ""
echo "Deployed @useorgx/openclaw-plugin@${VERSION}"
echo " Extensions: ${EXTENSIONS_DIR}"
printf " Installed paths:\\n"
for INSTALL_DIR in "${INSTALL_DIRS[@]}"; do
printf " - %s\\n" "$INSTALL_DIR"
done
echo " Gateway: restarted"
13 changes: 10 additions & 3 deletions scripts/live-dev-serve.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ import { fileURLToPath } from "node:url";
const scriptDir = resolve(fileURLToPath(new URL(".", import.meta.url)));
const repoRoot = resolve(scriptDir, "..");
const dashboardDir = resolve(repoRoot, "dashboard");
const extensionRoot = resolve(
process.env.HOME || "~",
".openclaw/extensions/openclaw-plugin"
const openclawHome = resolve(process.env.HOME || "~", ".openclaw");
const npmPluginRoot = resolve(
openclawHome,
"npm/node_modules/@useorgx/openclaw-plugin"
);
const legacyExtensionRoot = resolve(openclawHome, "extensions/openclaw-plugin");
const extensionRoot = process.env.ORGX_OPENCLAW_PLUGIN_EXTENSION_ROOT
? resolve(process.env.ORGX_OPENCLAW_PLUGIN_EXTENSION_ROOT)
: existsSync(npmPluginRoot)
? npmPluginRoot
: legacyExtensionRoot;
const gatewayPort = String(process.env.ORGX_DEV_GATEWAY_PORT || "18890").trim();

function log(message) {
Expand Down
13 changes: 13 additions & 0 deletions src/http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4880,6 +4880,19 @@ export function createHttpHandler(
return true;
}

// Legacy/direct chat links load the dashboard SPA. The chat surface is a
// dock within /orgx/live, while chat data APIs remain under /orgx/api/chat/*.
if (url === "/orgx/chat" || url.startsWith("/orgx/chat/")) {
const suffix = queryString && queryString.trim().length > 0 ? `?${queryString}` : "";
res.writeHead(302, {
Location: `/orgx/live${suffix}`,
...SECURITY_HEADERS,
...CORS_HEADERS,
});
res.end();
return true;
}

// Requests under /orgx/live
if (url === "/orgx/live" || url.startsWith("/orgx/live/")) {
const subPath = url.replace(/^\/orgx\/live\/?/, "");
Expand Down
20 changes: 20 additions & 0 deletions tests/http/workspace-hub-redirect.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,23 @@ test("legacy /workspace-hub deep links redirect to /orgx/live", async () => {
"/orgx/live?center=2577519c-d0bf-4682-a7ec-e9ab28d19822&view=activity"
);
});

test("legacy /orgx/chat deep links redirect to /orgx/live", async () => {
const config = baseConfig();
const client = { getBaseUrl: () => config.baseUrl };
const handler = createHttpHandler(config, client, () => null, createNoopOnboarding());

const res = createStubResponse();
const handled = await handler(
{
method: "GET",
url: "/orgx/chat?session=agent%3Amain%3Amain",
headers: {},
},
res
);

assert.equal(handled, true);
assert.equal(res.status, 302);
assert.equal(res.headers?.Location, "/orgx/live?session=agent%3Amain%3Amain");
});
Loading