chore: convert plugin to ESM and migrate to current openclaw plugin SDK
ESM conversion:
- plugin/package.json: add "type": "module".
- plugin/tsconfig.json: switch module/moduleResolution to "nodenext"; bump
target to ES2022.
- All relative imports across plugin/ now carry .js extensions as required
by Node ESM (nodenext module resolution).
- plugin/index.ts: replace `require('./calendar/schedule-cache')` with a
proper top-level import; switch `from 'os'` to `from 'node:os'`.
Plugin SDK convention update:
- Wrap default export with definePluginEntry({ id, name, description,
register }) per the current openclaw plugin authoring contract.
- Modernize plugin/openclaw.plugin.json: drop entry/version, add
activation.onStartup so gateway_start fires for this plugin at boot,
declare contracts.tools listing the five harborforge_* tools.
- Add a local plugin/openclaw-sdk.d.ts with ambient declarations for the
focused subpaths (openclaw/plugin-sdk/plugin-entry,
openclaw/plugin-sdk/core). We deliberately do NOT add openclaw as an
npm devDependency: the installer's `npm install --omit=dev` step trips
over openclaw's own (deeply nested) dependency graph when listed via
file:.../openclaw, and the runtime contract is provided by the gateway
loader anyway.
- The local PluginAPI interface is preserved (broader than the standard
OpenClawPluginApi — it surfaces `version`/`runtime`/`spawn`); the
register function is cast at the definePluginEntry boundary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,7 +29,7 @@ import {
|
|||||||
CalendarSlotResponse,
|
CalendarSlotResponse,
|
||||||
SlotAgentUpdate,
|
SlotAgentUpdate,
|
||||||
SlotStatus,
|
SlotStatus,
|
||||||
} from './types';
|
} from './types.js';
|
||||||
|
|
||||||
export interface CalendarBridgeConfig {
|
export interface CalendarBridgeConfig {
|
||||||
/** HarborForge backend base URL (e.g. "https://monitor.hangman-lab.top") */
|
/** HarborForge backend base URL (e.g. "https://monitor.hangman-lab.top") */
|
||||||
@@ -292,7 +292,7 @@ export class CalendarBridgeClient {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
import { hostname } from 'os';
|
import { hostname } from 'os';
|
||||||
import { getPluginConfig } from '../core/config';
|
import { getPluginConfig } from '../core/config.js';
|
||||||
|
|
||||||
export interface CalendarPluginConfig {
|
export interface CalendarPluginConfig {
|
||||||
/** Backend URL for calendar API (overrides monitor backendUrl) */
|
/** Backend URL for calendar API (overrides monitor backendUrl) */
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* • AgentWakeContext — context passed to agent when waking
|
* • AgentWakeContext — context passed to agent when waking
|
||||||
*
|
*
|
||||||
* Usage in plugin/index.ts:
|
* Usage in plugin/index.ts:
|
||||||
* import { createCalendarBridgeClient, createCalendarScheduler } from './calendar';
|
* import { createCalendarBridgeClient, createCalendarScheduler } from './calendar.js';
|
||||||
*
|
*
|
||||||
* const agentId = process.env.AGENT_ID || 'unknown';
|
* const agentId = process.env.AGENT_ID || 'unknown';
|
||||||
* const calendar = createCalendarBridgeClient(api, 'https://monitor.hangman-lab.top', agentId);
|
* const calendar = createCalendarBridgeClient(api, 'https://monitor.hangman-lab.top', agentId);
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
* scheduler.start();
|
* scheduler.start();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './types';
|
export * from './types.js';
|
||||||
export * from './calendar-bridge';
|
export * from './calendar-bridge.js';
|
||||||
export * from './scheduler';
|
export * from './scheduler.js';
|
||||||
export * from './schedule-cache';
|
export * from './schedule-cache.js';
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
|
import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
|
||||||
import { join, dirname } from 'path';
|
import { join, dirname } from 'path';
|
||||||
import { CalendarBridgeClient } from './calendar-bridge';
|
import { CalendarBridgeClient } from './calendar-bridge.js';
|
||||||
import {
|
import {
|
||||||
CalendarSlotResponse,
|
CalendarSlotResponse,
|
||||||
SlotStatus,
|
SlotStatus,
|
||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
SlotAgentUpdate,
|
SlotAgentUpdate,
|
||||||
CalendarEventDataJob,
|
CalendarEventDataJob,
|
||||||
CalendarEventDataSystemEvent,
|
CalendarEventDataSystemEvent,
|
||||||
} from './types';
|
} from './types.js';
|
||||||
|
|
||||||
export interface CalendarSchedulerConfig {
|
export interface CalendarSchedulerConfig {
|
||||||
/** Calendar bridge client for backend communication */
|
/** Calendar bridge client for backend communication */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { hostname } from 'os';
|
import { hostname } from 'os';
|
||||||
import { getPluginConfig } from '../core/config';
|
import { getPluginConfig } from '../core/config.js';
|
||||||
import { startManagedMonitor } from '../core/managed-monitor';
|
import { startManagedMonitor } from '../core/managed-monitor.js';
|
||||||
|
|
||||||
export function registerGatewayStartHook(api: any, deps: {
|
export function registerGatewayStartHook(api: any, deps: {
|
||||||
logger: any;
|
logger: any;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { stopManagedMonitor } from '../core/managed-monitor';
|
import { stopManagedMonitor } from '../core/managed-monitor.js';
|
||||||
|
|
||||||
export function registerGatewayStopHook(api: any, deps: {
|
export function registerGatewayStopHook(api: any, deps: {
|
||||||
logger: any;
|
logger: any;
|
||||||
|
|||||||
@@ -11,18 +11,20 @@
|
|||||||
* served directly by the plugin when Monitor queries via the
|
* served directly by the plugin when Monitor queries via the
|
||||||
* local monitor_port communication path.
|
* local monitor_port communication path.
|
||||||
*/
|
*/
|
||||||
import { hostname, freemem, totalmem, uptime, loadavg, platform } from 'os';
|
import { hostname, freemem, totalmem, uptime, loadavg, platform } from 'node:os';
|
||||||
import { getPluginConfig } from './core/config';
|
import { definePluginEntry } from 'openclaw/plugin-sdk/plugin-entry';
|
||||||
import { MonitorBridgeClient, type OpenClawMeta } from './core/monitor-bridge';
|
import { MultiAgentScheduleCache } from './calendar/schedule-cache.js';
|
||||||
import type { OpenClawAgentInfo } from './core/openclaw-agents';
|
import { getPluginConfig } from './core/config.js';
|
||||||
import { registerGatewayStartHook } from './hooks/gateway-start';
|
import { MonitorBridgeClient, type OpenClawMeta } from './core/monitor-bridge.js';
|
||||||
import { registerGatewayStopHook } from './hooks/gateway-stop';
|
import type { OpenClawAgentInfo } from './core/openclaw-agents.js';
|
||||||
|
import { registerGatewayStartHook } from './hooks/gateway-start.js';
|
||||||
|
import { registerGatewayStopHook } from './hooks/gateway-stop.js';
|
||||||
import {
|
import {
|
||||||
createCalendarBridgeClient,
|
createCalendarBridgeClient,
|
||||||
createCalendarScheduler,
|
createCalendarScheduler,
|
||||||
CalendarScheduler,
|
CalendarScheduler,
|
||||||
AgentWakeContext,
|
AgentWakeContext,
|
||||||
} from './calendar';
|
} from './calendar/index.js';
|
||||||
|
|
||||||
interface PluginAPI {
|
interface PluginAPI {
|
||||||
logger: {
|
logger: {
|
||||||
@@ -53,10 +55,7 @@ interface PluginAPI {
|
|||||||
getAgentStatus?: () => Promise<{ status: string } | null>;
|
getAgentStatus?: () => Promise<{ status: string } | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
function register(api: PluginAPI): void {
|
||||||
id: 'harbor-forge',
|
|
||||||
name: 'HarborForge',
|
|
||||||
register(api: PluginAPI) {
|
|
||||||
const logger = api.logger || {
|
const logger = api.logger || {
|
||||||
info: (...args: any[]) => console.log('[HarborForge]', ...args),
|
info: (...args: any[]) => console.log('[HarborForge]', ...args),
|
||||||
error: (...args: any[]) => console.error('[HarborForge]', ...args),
|
error: (...args: any[]) => console.error('[HarborForge]', ...args),
|
||||||
@@ -290,7 +289,6 @@ export default {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Multi-agent sync + check loop
|
// Multi-agent sync + check loop
|
||||||
const { MultiAgentScheduleCache } = require('./calendar/schedule-cache') as typeof import('./calendar/schedule-cache');
|
|
||||||
const scheduleCache = new MultiAgentScheduleCache();
|
const scheduleCache = new MultiAgentScheduleCache();
|
||||||
|
|
||||||
const SYNC_INTERVAL_MS = 300_000; // 5 min
|
const SYNC_INTERVAL_MS = 300_000; // 5 min
|
||||||
@@ -595,5 +593,16 @@ export default {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
logger.info('HarborForge plugin registered (id: harbor-forge)');
|
logger.info('HarborForge plugin registered (id: harbor-forge)');
|
||||||
},
|
}
|
||||||
};
|
|
||||||
|
// HarborForge's local PluginAPI is broader than the standard OpenClawPluginApi
|
||||||
|
// (it surfaces optional `version`/`runtime`/`spawn` accessors that older
|
||||||
|
// OpenClaw builds exposed). The cast at the definePluginEntry boundary
|
||||||
|
// acknowledges that gap — the runtime api object is whatever the gateway
|
||||||
|
// passes us, and each access is guarded with optional chaining / fallbacks.
|
||||||
|
export default definePluginEntry({
|
||||||
|
id: 'harbor-forge',
|
||||||
|
name: 'HarborForge',
|
||||||
|
description: 'HarborForge plugin for OpenClaw - project management, monitoring, and CLI integration',
|
||||||
|
register: register as (api: any) => void,
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
{
|
{
|
||||||
"id": "harbor-forge",
|
"id": "harbor-forge",
|
||||||
"name": "HarborForge",
|
"name": "HarborForge",
|
||||||
"version": "0.2.0",
|
|
||||||
"description": "HarborForge plugin for OpenClaw - project management, monitoring, and CLI integration",
|
"description": "HarborForge plugin for OpenClaw - project management, monitoring, and CLI integration",
|
||||||
"entry": "./dist/index.js",
|
"activation": {
|
||||||
|
"onStartup": true
|
||||||
|
},
|
||||||
|
"contracts": {
|
||||||
|
"tools": [
|
||||||
|
"harborforge_status",
|
||||||
|
"harborforge_telemetry",
|
||||||
|
"harborforge_monitor_telemetry",
|
||||||
|
"harborforge_calendar_status",
|
||||||
|
"harborforge_calendar_complete"
|
||||||
|
]
|
||||||
|
},
|
||||||
"configSchema": {
|
"configSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "harbor-forge-plugin",
|
"name": "harbor-forge-plugin",
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"description": "OpenClaw plugin for HarborForge monitor bridge and CLI integration",
|
"description": "OpenClaw plugin for HarborForge monitor bridge and CLI integration",
|
||||||
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "CommonJS",
|
"module": "nodenext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "nodenext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user