L/XschedulerView source ↗

Offline demo · no login · zero posts

Inspect a scheduled week
without opening Chrome.

This viewer replays the same manifest shape as the real CLI. Every action below is simulated and no social network is contacted.

60-second deterministic replay

Sample week

Read the fixture, validate each packet, follow the mock adapter's five steps, then compare demo and live boundaries below.

Loading fixture…

Architecture

One manifest, one orchestrator, replaceable platform adapters.

Manifest

Content, media, target platform, wall-clock schedule, timezone, and account guard form one versionable input.

Validator

Rejects missing text/assets, incompatible media counts, duplicate IDs, and unsupported platform/template combinations before a composer opens.

Orchestrator

Orders work, injects adapters, resumes verified posts, stops on safety failures, and owns the final run report.

Adapters

Contain volatile selectors and native-UI details. Core batching and state logic stay independent of either platform.

Workflow and state

Every item advances through observable, resumable states.

  1. 01validated

    Schema, assets, account, and schedule checked.

  2. 02composed

    Text and media placed in the native composer.

  3. 03scheduled

    Native schedule controls receive the wall-clock value.

  4. 04verified

    The scheduled queue is reconciled as source of truth.

  5. 05reported

    State, screenshots, and outcome remain available for resume.

Duplicate guard

Verified state and live-queue reconciliation prevent a retry from silently scheduling the same item twice.

Live-publish guard

If an adapter detects immediate publication, the entire batch aborts and raises an operator alert.

Bounded retries

Selector or verification failures stop with precise state; the orchestrator does not loop blindly.

Real, linked code

The safety properties live in the core, not in screenshots.

DEMO ADAPTERdemo-adapter.js ↗
return {
  id: post.id,
  platform: post.platform,
  status: 'simulated',
  steps: labels.map((label, index) => ({
    id: index + 1, label, status: 'complete'
  }))
};

The public replay consumes the real manifest shape and returns the common report contract without importing CDP.

IDEMPOTENT RESUMEorchestrator.js ↗
if (core.state.isVerified(postId)) {
  core.runLog.append({
    postId, action: 'skip', result: 'already-verified'
  });
  continue;
}

A verified item is skipped before any platform action; the durable state survives interrupted batches.

CRITICAL STOPorchestrator.js ↗
if (error instanceof LivePublishError || error.critical) {
  this.alertOperator(error.message);
  return this.finish(OUTCOME.ABORTED, error.message);
}

A single potentially live post stops the whole batch instead of allowing later items to continue.

Execution boundaries

Same batch contract. Three deliberately different capabilities.

Demo mode
Local fixture + mock adapter + static report. No Playwright import, CDP, social URL, or external write.

Dry-run mode
Attaches to Chrome and rehearses the native flow, but stubs the terminal schedule click.

Live mode
Requires explicit --live, uses native schedule UI, then verifies each queue.

Quality and limits

Automation is treated as an operator tool, not an unattended promise.

0demo external writes
5observable steps per item
2independent live adapters
1durable state contract

Run locally

Replay first. Attach later.

npm install
npm run demo
npm test

# only after reviewing the batch:
node src/cli.js --batch ./my-week --dry-run