Skip to content

Latest commit

 

History

History
295 lines (214 loc) · 8.61 KB

File metadata and controls

295 lines (214 loc) · 8.61 KB

Core Public API

This document defines the public surface of @aro/core. Core is the headless engine for workspace management, job execution, persistence, and validation. It runs in Node.js only; Desktop (or another host) creates a Core instance and forwards operations.

Entry point

import { createCore } from '@aro/core';

const core = createCore({ workspaceRoot: '/path/to/workspace' });
// ... use core
core.shutdown();

createCore

function createCore(options: AroCoreOptions): AroCore

Creates a Core instance for the given workspace. Initializes .aro/ directory and SQLite database. Call core.shutdown() before releasing the instance.

Options:

Property Type Required Description
workspaceRoot string Yes Absolute path to the workspace directory
dbPath string No Override SQLite path (default: workspaceRoot/.aro/aro.sqlite)
tokensPath string No Override tokens file path (default: tokens/tokens.json)

AroCore interface

The returned object provides the following services.

workspace

Scoped file access within the workspace. Paths are relative; ../ traversal is blocked.

Method Description
initWorkspace() Ensures .aro/ exists
resolve(path) Resolves a relative path; throws on ../
readText(path) Reads file content as string
writeText(path, content) Writes file content
exists(path) Returns true if file exists
mkdirp(dir) Creates directory recursively

runs

Run lifecycle: start, finish, query.

Method Description
startRun(params?) Starts a run; returns { runId }
finishRun({ runId, status }) Finishes run with success, error, or cancelled
getRun(runId) Returns Run or null
listRuns(filter?) Returns runs ordered by time (newest first)

logs

Log entries for runs. Persisted in SQLite.

Method Description
appendLog({ runId, level, message }) Appends a log entry
listLogs(runId) Returns all entries for a run
subscribe(runId, handler) Subscribes to new entries; returns unsubscribe function

artifacts

Artifacts are files written under .aro/artifacts/<runId>/. Indexed in SQLite.

Method Description
writeArtifact({ runId, path, content }) Writes artifact; returns Artifact
listArtifacts(runId) Returns artifacts for a run

jobs

Job registration and execution. Jobs receive a JobContext with logger, workspace facet, artifact writer, and abort signal.

Method Description
register(jobDef) Registers a job definition
run(jobKey, input) Runs a job; returns { runId }
cancel(runId) Cancels a running job via AbortSignal

tokens

Load/save tokens from workspace (e.g. tokens/tokens.json).

Method Description
loadTokens() Loads tokens from disk; returns parsed JSON or empty object
saveTokens(tokens) Saves tokens to disk
diffTokens(a, b) Returns TokenDiff (added, removed, changed keys)

validation

Zod-based validation at boundaries.

Method Description
validateTokens(tokens) Returns ValidationResult with ok and optional issues

shutdown

core.shutdown(): void

Closes the database and clears subscriptions. Call before discarding the Core instance.


Types

Run

interface Run {
  id: string;
  status: string;
  startedAt: number;
  finishedAt: number | null;
  createdAt: number;
}

LogEntry

interface LogEntry {
  id: string;
  runId: string;
  level: string;
  message: string;
  createdAt: number;
}

Artifact

interface Artifact {
  id: string;
  runId: string;
  path: string;
  createdAt: number;
}

JobDefinition

interface JobDefinition {
  key: string;
  run: (ctx: JobContext, input: unknown) => void | Promise<void>;
}

JobContext

Provided to job run functions.

interface JobContext {
  readonly logger: RunLogger;        // (level, message) => void
  readonly workspace: WorkspaceFacet; // resolve, readText, writeText, exists, mkdirp
  readonly artifactWriter: ArtifactWriter; // ({ path, content }) => Artifact
  readonly abort: AbortSignal;
  progress?: (value: number | { current: number; total: number }) => void;
}

ValidationResult

interface ValidationResult {
  ok: boolean;
  issues?: ValidationIssue[];
}

interface ValidationIssue {
  path: string;
  message: string;
}

TokenDiff

interface TokenDiff {
  added: string[];
  removed: string[];
  changed: string[];
}

Module Registry

Shared server-side registry for module initialization. Both hosts register their modules with these functions; all registry logic lives in @aro/core.

import { registerModule, resolveConfig, loadModules } from '@aro/core';
import { init as inspectInit } from '@aro/module-inspect';

// 1. Register modules
registerModule('inspect', inspectInit);

// 2. Resolve tenant config
resolveConfig(configDir);

// 3. Load modules into a Core instance
loadModules(core, setRegisteredJobKeys);

Registry API

Function Description
registerModule(key, init) Registers a ModuleInit function under the given key
getInit(key) Returns the ModuleInit for a key, or undefined
getRegisteredModuleKeys() Returns all registered module keys
resolveConfig(configDir) Loads tenant config via @aro/config; caches result
getResolvedConfig() Returns the cached config (throws if not yet resolved)
getUIModel() Returns the current UI model from resolved config
getEnabledModuleKeys() Returns enabled module keys (with unknown-key warnings)

Module Loader

Function Description
loadModules(core, setRegisteredJobKeys) Initializes enabled modules on a Core instance. Standalone mode loads only the first module. Calls setRegisteredJobKeys with accumulated job keys.

CoreAdapter

Reference adapter that wraps AroCore to produce an AroPreloadAPI-compatible object. Both Desktop (IPC) and Web (HTTP/WS) delegate their Core operations through this adapter — the transport layer remains host-specific, but operation logic is defined once here. Also usable directly for contract tests.

import { createCoreAdapter } from '@aro/core';

// Contract test usage (minimal options)
const api = createCoreAdapter(core, {
  uiModel: 'standalone',
  enabledModules: ['inspect'],
  workspaceRoot: '/path/to/workspace',
});

// Host usage (full options)
const api = createCoreAdapter(core, {
  uiModel: config.uiModel,
  enabledModules: config.enabledModules,
  workspaceRoot: getCurrentWorkspacePath()!,
  tenantConfig: config,
  getRegisteredJobKeys,
});

Options (CoreAdapterOptions):

Property Type Required Description
uiModel UIModel Yes Which UI model the adapter reports
enabledModules string[] Yes Module keys the adapter reports as enabled
workspaceRoot string Yes Absolute path to the workspace
tenantConfig TenantConfig No Full config; when set, getTenantConfig() returns it verbatim
getRegisteredJobKeys () => string[] No Job key accessor; when set, job.listRegistered() uses it instead of enabledModules

Versioning

AroCore_v1 is a type alias for the current AroCore interface (exported from @aro/types). When a breaking change lands, a new alias (AroCore_v2) will be introduced while the old version remains available during migration. Additive, non-breaking changes (new optional methods) do not bump the version.


Exports

From @aro/core:

  • createCore
  • createCoreAdapter
  • registerModule, getInit, getRegisteredModuleKeys
  • resolveConfig, getResolvedConfig, getUIModel, getEnabledModuleKeys
  • loadModules
  • Types: AroCore, AroCore_v1, AroCoreOptions, CoreAdapterOptions, ModuleInit, Run, LogEntry, Artifact, ValidationIssue, ValidationResult, TokenDiff, JobDefinition, JobContext