Commit Graph

48 Commits

Author SHA1 Message Date
gsknnft 083c146aac feat: add runtime seam, Hermes adapter support, and demo gateway mode (#89)
* fix: include kanbanImmersive in immersiveOverlayActive calculation

When Kanban board is open, HUD elements (camera preset buttons, edit toolbar, overlays) should be suppressed. The kanbanImmersive flag was defined but not included in the immersiveOverlayActive condition, causing HUD elements to remain visible.

This fix adds kanbanImmersive to the immersiveOverlayActive calculation so HUD elements are properly hidden when the Kanban board is open.

Co-authored-by: Luke The Dev <iamlukethedev@users.noreply.github.com>

* Fix: Hide mini status bar when Kanban immersive overlay is open

Wraps the bottom-left mini status bar (showing agent stats, vibe score, and
control hints) with !immersiveOverlayActive check to match the behavior of
other HUD elements like camera controls and toolbar.

This ensures the status bar is properly hidden when the Kanban board or any
other immersive overlay is active, maintaining a clean immersive experience.

Co-authored-by: Luke The Dev <iamlukethedev@users.noreply.github.com>

* chore: drop unrelated package-lock line from branch

Co-authored-by: Luke The Dev <iamlukethedev@users.noreply.github.com>

* universal-backend-plan

* backend-neutral runtime seam

* package.json update

* feat: add Hermes gateway adapter as alternative to OpenClaw

Adds a WebSocket adapter that lets Claw3D connect to a Hermes AI agent
runtime without any changes to the frontend. The adapter implements the
full Claw3D gateway protocol and bridges it to the Hermes HTTP API.

Changes:
- server/hermes-gateway-adapter.js: WebSocket bridge implementing the
  Claw3D gateway protocol against the Hermes HTTP API. Supports all
  core methods (agents, sessions, chat streaming, cron, config, files,
  approvals) and multi-agent orchestration via spawn_agent/delegate_task
  tools. Persists conversation history to ~/.hermes/clawd3d-history.json.
- scripts/clawd3d-start.sh: All-in-one startup script that launches
  Hermes, the adapter, and the Next.js dev server with auto port
  conflict resolution. Alias as `claw3d` for convenience.
- src/features/office/hooks/useCronAgents.ts: Hook that polls the
  gateway for cron-scheduled agents and surfaces them in the 3D office.
- package.json: adds `hermes-adapter` npm script
- .env.example: documents Hermes config vars
- docs/hermes-gateway.md: setup guide and protocol reference

Usage:
  npm run hermes-adapter   # start adapter (connect to http://localhost:8642)
  npm run dev              # start Claw3D, point browser at localhost:3000
  # or: bash scripts/clawd3d-start.sh  (starts everything automatically)

Both OpenClaw and Hermes are supported simultaneously — the gateway URL
in NEXT_PUBLIC_GATEWAY_URL determines which backend Claw3D connects to.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add read_agent_context tool for cross-agent coordination

Agents can now read each other's conversation history via the
read_agent_context tool, enabling the orchestrator to check what
a sub-agent has done before re-delegating work.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: wire Hermes office UX and role-aware runtime updates

* feature update - demomode & hermes adapter

* fix lint blockers

* lintfix #2

* fix: stabilize retro office camera preset callbacks

* Initial plan

* fix: stabilize retro office overview preset hooks

Agent-Logs-Url: https://github.com/gsknnft/Claw3D/sessions/9cc71555-591e-44cf-aec4-25affbdcb405

Co-authored-by: gsknnft <123185582+gsknnft@users.noreply.github.com>

* feat: add truthful backend selection, Hermes adapter hardening, and demo gateway mode

* fix: address bugbot review and finalize backend selection

* fixed - onboarding and hermes calls

* office systems roadmap

* feat specs in docs

* specs ready

* feat: continue custom runtime seam and gateway alignment

* custom lane wired

* feat: add custom runtime provider path and office runtime alignment

* runtime fixes

* fix lukes findings

* fix lukes findings #2

* stable UI & connect screen page -> overlay

* better baseline for connection

* stable providers & ui rendering

* best launch yet

* nearly no gateway on reconnect

* auto reconnect last state

* fix: preserve selected runtime across reconnects

Keep backend selection aligned with the operator's chosen runtime instead of reviving a mismatched last-known-good adapter, and keep custom runtimes prompting for reconnect when Studio cannot auto-connect them.

Made-with: Cursor

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Luke The Dev <iamlukethedev@users.noreply.github.com>
Co-authored-by: Elias Pfeffer <eliaspfeffer@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-04-02 15:27:24 -05:00
Luke The Dev a997f13601 feat(kanban): Interactive Kanban board with real-time task tracking (#83)
* feat(kanban): add Kanban board with task-manager skill, modal UI, and desk clutter

Implement a full Kanban board system for tracking agent tasks:
- Add task-manager skill with shared JSON task store for persistence
- Render board as a floating modal over the live 3D office (not immersive)
- Auto-create tasks from actionable user messages with heuristic filtering
- Sync task status through OpenClaw agent lifecycle events
- Collapse task details panel by default, expand on card click
- Add dynamic desk clutter (papers, folders, etc.) reflecting active task count
- Exclude done tasks from desk clutter count
- Extract KANBAN_CLUTTER_OFFSET for easy positioning adjustment
- Add install flow with progress bar for the task-manager skill
- Include unit and e2e test coverage

Made-with: Cursor

* feat(kanban): production-harden task board with AI-free classification, resilient persistence, and modal UX

- Harden shared task store with atomic writes, payload size limits, and server-side enum validation
- Add client resilience: request timeouts (AbortController), exponential backoff retries, poll deduplication
- Implement optimistic UI with rollback on all card mutations (update, move, archive)
- Add modal accessibility: focus trap, Escape to close, aria-modal, keyboard card navigation
- Trust OpenClaw agent lifecycle phase=start as task classification signal instead of regex heuristics
- Keep regex heuristic only as lightweight filter for direct chat events (conversational noise)
- Expand verb recognition with typo tolerance and broader action vocabulary
- Create tasks from agent runs even when no chat event is received (external channel support)
- Merge dual header bars into single bar; reposition close button outside modal corner
- Exclude done tasks from desk clutter count; make clutter position configurable via KANBAN_CLUTTER_OFFSET
- Update default furniture layout to match user configuration
- Ensure kanban_board furniture persists in local storage across sessions
- Add comprehensive test coverage for store, API route, and controller logic

Made-with: Cursor

---------

Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-03-30 22:58:18 -05:00
robotica4us-collab 464a49bb6d fix(navigation): block desk_cubicle in nav grid with zero padding to prevent walk-through (#75)
- desk_cubicle now has blocksNavigation: true with navPadding: 0
  (tight blocking, no inflation — aisles stay clear)
- buildNavGrid reads per-item navPadding from ITEM_METADATA
- getDeskLocations targets y-5 (chair position, above desk blocked zone)
- Agents route AROUND desks instead of through them
- Chair stays passable so agents can reach their sitting position

Fixes object passthrough for desks. Other large passable items
(doors, lamps) unchanged — they remain non-blocking by design.

Co-authored-by: Neo (subagent) <neo@openclaw.local>
Co-authored-by: Luke The Dev <252071647+iamlukethedev@users.noreply.github.com>
2026-03-28 22:08:05 -05:00
dependabot[bot] 4b7b295846 build(deps): bump the npm_and_yarn group across 1 directory with 5 updates (#64)
Bumps the npm_and_yarn group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [next](https://github.com/vercel/next.js) | `16.1.6` | `16.1.7` |
| [minimatch](https://github.com/isaacs/minimatch) | `3.1.2` | `3.1.5` |
| [flatted](https://github.com/WebReflection/flatted) | `3.3.3` | `3.4.2` |
| [picomatch](https://github.com/micromatch/picomatch) | `2.3.1` | `2.3.2` |
| [picomatch](https://github.com/micromatch/picomatch) | `4.0.3` | `4.0.4` |
| [rollup](https://github.com/rollup/rollup) | `4.57.0` | `4.60.0` |



Updates `next` from 16.1.6 to 16.1.7
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.6...v16.1.7)

Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

Updates `flatted` from 3.3.3 to 3.4.2
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2)

Updates `picomatch` from 2.3.1 to 2.3.2
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

Updates `picomatch` from 4.0.3 to 4.0.4
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

Updates `rollup` from 4.57.0 to 4.60.0
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.57.0...v4.60.0)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.1.7
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: rollup
  dependency-version: 4.60.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-28 22:05:57 -05:00
Luke The Dev c3556d2daa fix(security): close remaining path validation gaps (#77)
Harden the SSH agent-state and skill-removal paths to match the local security model, and avoid rejecting valid local workspace skill removals.

Made-with: Cursor

Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-03-27 22:21:41 -05:00
AdminExcellence e0eb73111b fix(security): sanitize file paths in agent-state and skills-remove endpoints (#60)
Co-authored-by: Shams <shams@openclaw.dev>
2026-03-27 22:21:03 -05:00
robotica4us-collab 3295e1ea0e fix(skills): sync packaged soundclaw SKILL.md with asset source (fixes #72) (#74)
The embedded SOUNDCLAW_SKILL_MD string in packaged.ts was missing the
'OpenClaw Gateway Skill Contract' section that was added to the asset
source file in #67. Re-synced the packaged constant from the canonical
assets/skills/soundclaw/SKILL.md.

Co-authored-by: Neo (subagent) <neo@openclaw.local>
2026-03-27 21:35:51 -05:00
iamlukethedev e71b62444c fix: resolve gateway URL at runtime via /api/studio fallback (#66)
Fixes #57 — NEXT_PUBLIC_GATEWAY_URL is a build-time variable that gets
baked into the client bundle. Changing it in .env and restarting has no
effect without a rebuild.

- normalizeLocalGatewayDefaults now accepts the sanitized public form
  ({url, tokenConfigured}) from /api/studio
- When no saved gateway URL exists, prefer runtime localGatewayDefaults
  (from openclaw.json or CLAW3D_GATEWAY_URL env var) over the
  potentially stale build-time NEXT_PUBLIC_GATEWAY_URL
- loadLocalGatewayDefaults falls back to CLAW3D_GATEWAY_URL/TOKEN env
  vars when openclaw.json is absent
- Added runtime env vars documentation to .env.example and README

Co-authored-by: robotica4us-collab <neo@openclaw.ai>
Made-with: Cursor
2026-03-27 14:45:02 -05:00
iamlukethedev 456cfae771 fix(issue-7): revert dev artifact and fix test timeouts
- Revert next.config.ts: remove hardcoded Cloudflare tunnel URL from
  allowedDevOrigins (dev artifact, not part of the voice upload fix).
- Rewrite voice transcribe tests to use mock request objects instead of
  real Request/FormData/Blob instances that cause formData() to hang
  indefinitely in vitest's Node environment. All 9 tests now pass.

Made-with: Cursor
2026-03-27 13:42:03 -05:00
robotica4us-collab fdc7a4223a fix(issue-7): enforce voice upload size limit before buffering (#22)
* fix(voice): enforce upload size limit before buffering (issue #7)

The previous implementation called request.formData() and audio.arrayBuffer()
before checking MAX_VOICE_UPLOAD_BYTES, meaning oversized uploads were fully
buffered into memory before rejection — a DoS/OOM risk.

Changes:
- Check Content-Length header early and return 413 if it exceeds the limit,
  preventing any request body from being read into memory for oversized uploads
- Export MAX_VOICE_UPLOAD_BYTES for use in tests
- Switch from instanceof File to duck-typing (checking .arrayBuffer method)
  to avoid cross-realm failures in jsdom test environments
- Return HTTP 413 Payload Too Large for oversized uploads (was 400 before)
- Retain a secondary post-buffer size check to catch missing/spoofed
  Content-Length headers

Tests added (tests/unit/voiceTranscribe.test.ts):
- Content-Length exceeding limit → 413 before any buffering
- Content-Length at exactly the limit → proceeds normally
- No Content-Length header, small file → proceeds normally (200)
- No Content-Length header, oversized body → 413 after buffering
- Missing audio field → 400
- Empty audio file (0 bytes) → 400
- Malformed Content-Length header → falls through gracefully

Fixes: issue #7

* fix(issue-7): account for multipart overhead in Content-Length early check

The early Content-Length guard was comparing total multipart request size
against MAX_VOICE_UPLOAD_BYTES, but multipart/form-data includes boundary
and header overhead (~200-500 bytes). A valid file at exactly the 20 MB
limit was being rejected with 413.

Fix: add a 1 KB MULTIPART_OVERHEAD_ALLOWANCE to the early check threshold.
The post-buffer check remains the authoritative limit and measures actual
audio bytes. Updated tests to reflect the corrected early-check boundary.

---------

Co-authored-by: Neo (subagent) <neo@openclaw.local>
Co-authored-by: Neo <neo@openclaw.ai>
2026-03-27 13:41:56 -05:00
iamlukethedev fcecece1c3 fix(test): correct same-cell astar assertion to match code behavior
The test expected [] for same-cell targets, but the code correctly
returns [{ x: ex, y: ey }] so the movement layer can make the final
fine-grained adjustment to the exact pixel.

Made-with: Cursor
2026-03-27 13:19:47 -05:00
robotica4us-collab 450f4873f6 fix(issue-3): astar() returns empty path on failure instead of raw destination (#21)
* fix(navigation): astar() returns [] on failure instead of raw destination

Issue #3: When A* could not find a route, it returned [{x: endX, y: endY}]
(the raw destination) as a one-element path. The movement layer treated
this as a valid waypoint and steered agents in a straight line toward the
target, letting them pass through walls and furniture.

Changes:
- navigation.ts: Both failure exits in astar() now return [] instead of
  [{x: ex, y: ey}]. This applies to:
    * findFree() returning null (start or end hopelessly blocked)
    * start and end resolving to the same free cell (already arrived)
    * open list exhausted with no route to the end
- RetroOffice3D.tsx: Movement-layer waypoint fallback changed from
  agent.targetX/Y to agent.x/agent.y when path is empty. An agent with
  no route now stays put rather than walking through obstacles.

Tests added (tests/unit/navigation.astarFallback.test.ts):
- astar returns [] for an unreachable destination (thick wall barrier)
- astar returns [] when the entire grid is blocked (findFree fails)
- astar returns a valid path for reachable destinations (regression)
- astar returns [] when start and end snap to the same grid cell
- movement-layer simulation: empty path keeps agent at current position

* fix(navigation): preserve final waypoint for same-cell reachable targets

astar() was returning [] for both true pathfinding failures and same-cell
reachable targets, causing the movement layer to treat both cases identically
(agent stays put). A destination within the same nav cell is still reachable
— the agent should take the final fine-grained step to the exact pixel.

Fix: return [{ x: ex, y: ey }] for same-cell case so the movement layer
can settle the agent onto the exact interaction point.

---------

Co-authored-by: Neo (subagent) <neo@openclaw.local>
Co-authored-by: Neo <neo@openclaw.ai>
2026-03-27 13:19:39 -05:00
robotica4us-collab b091b9087a fix(issue-13): remove impossible TS2367 comparison in skillGymDirective guard (#18)
* fix(issue-13): remove impossible TS2367 comparison in skillGymDirective guard

OfficeGymDirective is defined as the literal type 'gym' (deskDirectives.ts:9).
The condition at eventTriggers.ts:1136

    if (skillGymDirective.directive !== 'release')

compared it against 'release', which TypeScript correctly flags as an
impossible comparison (TS2367), blocking the build.

The check was copy-pasted from the desk/github/qa patterns where 'release'
is a valid directive value. For the gym skill path there is no 'release'
directive — gym hold is released via the isAgentRunning guard in
reduceOfficeGymHoldState (deskDirectives.ts). Any non-null skillGymDirective
should therefore unconditionally set skillGymHoldByAgentId.

Fix: remove the dead guard and set the hold directly, with an explanatory
comment. Verified with npm run typecheck (exits 0).

* test(eventTriggers): add gym directive hold unit tests (issue #13)

Tests for the skillGymHold logic in reconcileOfficeAnimationTriggerState:
- Verify gym directive sets skillGymHoldByAgentId unconditionally (no release guard)
- Verify gym directive via transcript entry triggers hold
- Verify prior hold persists when no new directive is present
- Verify no hold entry when neither directive nor prior hold exists
- Verify multiple agents are handled independently

* fix(issue-13): handle release directive in skillGym hold reconciliation

OfficeGymDirective = 'gym' | 'release'. The previous unconditional
skillGymHoldByAgentId[agentId] = true would silently ignore a release
directive and keep the agent in gym-hold state indefinitely.

Fix: only set the hold when directive === 'gym'. A release directive
now skips the assignment, clearing the hold as intended.

Context: reconcileOfficeAnimationTriggerState tracks the skill-source
gym path (resolveOfficeGymDirective, source: 'skill'). The manual/command
release path (source: 'manual') is handled separately by buildOfficeAnimationState
→ reduceOfficeGymHoldState, which was already correct.

Tests updated: corrected the file-level doc comment, renamed the 'gym'
test for clarity, added a regression test confirming a release-pattern
message does not set the hold.

---------

Co-authored-by: Neo (subagent) <neo@openclaw.local>
Co-authored-by: Neo <neo@openclaw.ai>
Co-authored-by: Luke The Dev <252071647+iamlukethedev@users.noreply.github.com>
2026-03-27 13:05:25 -05:00
Luke The Dev a953c5fda6 feat: add company builder wizard with AI-powered org generation (#73)
* feat: add company builder wizard with AI-powered org generation

Adds a new "Build Your Company" step to the onboarding wizard that lets
users describe their business and generates a full agent org structure
using OpenClaw's AI. Includes company plan generation, role deduplication,
agent bootstrap with main-agent reuse, org chart preview, confetti on
success, CSS voxel running-avatar loader, amber theme unification, and
best-effort SSH workspace cleanup.

Made-with: Cursor

* fix: resolve lint errors in CompanyBuilderModal

Replace setState-in-effect pattern with a direct callback, escape
apostrophes in JSX text, and derive org chart hover state without
side effects.

Made-with: Cursor

---------

Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-03-27 12:59:44 -05:00
Luke The Dev 3da1694085 feat: add SOUNDCLAW jukebox skill integration (#67)
Add the office jukebox flow so Spotify can be controlled from the SOUNDCLAW skill, manual jukebox UI, and local browser auth bridge during development.

Made-with: Cursor
2026-03-26 18:35:19 -05:00
Luke The Dev a202cdc80f feat: add multi-agent beta remote office support (#62)
* Remote openclaw connection enabled and agent added

* 2 worlds connected

* Performance improvement

* Performance improvements

* Added documentation

* feat(office): add multi-agent beta remote office support

Add a second-office beta that can mirror remote Claw3D presence or derive remote gateway presence so teams can visualize and message agents across instances. Harden the new remote flows, document setup, and keep the branch green with full validation.

Made-with: Cursor

---------

Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-03-25 11:14:20 -05:00
Luke The Dev 1185f7a9f0 Updated Roadmap (#59)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-24 14:15:47 -05:00
Nix 6666be0652 fix(security): resolve symlinks in path-suggestions home directory check (fixes #52) (#54)
The isWithinHome() check used path.relative() which is purely string-based
and does not follow symlinks. A symlink inside the home directory pointing
to an external path would bypass the containment check, allowing directory
listing of arbitrary filesystem locations.

Now uses fs.realpathSync() to resolve symlinks before the containment
comparison, ensuring the real filesystem path is validated.

Co-authored-by: ThankNIXlater <ThankNIXlater@users.noreply.github.com>
2026-03-24 11:03:24 -05:00
emiliovos 88b1e9b749 docs: add Agent Bus integration guide — visualize AI coding sessions in Claw3D (#47)
Agent Bus is an open-source event routing system that bridges AI coding
agents (Claude Code, Gemini, Codex) to Claw3D's 3D office. It includes
an OpenClaw-compatible gateway at :18789 that speaks the same protocol —
no Claw3D code changes needed, just point GATEWAY_URL.

Zero inference cost, works with any agent that can HTTP POST.
2026-03-24 11:02:58 -05:00
Yusup Supriyadi 994c8b06b5 feat(ui): improve visual polish, responsiveness, and accessibility (#58)
* feat(ui): improve visual polish, responsiveness, and UX consistency

- GatewayConnectScreen: replace hardcoded text-white* with semantic
  foreground/muted-foreground tokens so the connect form is readable
  in both light and dark modes
- HeaderBar: show gateway status chip for "connected" state in addition
  to "connecting", giving users clear visual feedback once connected
- FleetSidebar: add aria-label and aria-pressed to agent row buttons
  for screen-reader accessibility
- HQSidebar: add role=tablist/tab/tabpanel, aria-selected, aria-controls,
  and aria-labelledby to the headquarters panel tabs
- OfficePage: replace Suspense fallback={null} with a themed spinner
  so users see feedback instead of a blank screen during initial load

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(office): widen agent nameplate to prevent name truncation

- Expand background plane from 0.68 to 1.1 width
- Increase maxWidth from 0.56 to 1.0
- Slightly reduce fontSize 0.1 to 0.09 for better fit
- Add whiteSpace nowrap to prevent wrapping
- Truncate names >14 chars with ellipsis for very long agent names

---------

Co-authored-by: Claw3D UI Bot <ui-improvements@claw3d.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 10:55:19 -05:00
Luke The Dev c9789c2148 Add office agent management wizard (#56)
* Add agents

* Agent

* Added agents management

* Polish agent wizard and release blockers.

Finalize the office agent management flow by aligning the gateway fallback behavior, cleaning up UI semantics, and updating tests so the branch is ready to ship.

Made-with: Cursor

---------

Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-03-23 18:04:37 -05:00
Luke The Dev 5e7812c352 Skills (#50)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-23 11:44:25 -05:00
robotica4us-collab c2cbdeec44 feat(issue-17): add onboarding wizard for new users (#26)
* feat(issue-17): add onboarding wizard for new users

Adds a step-based onboarding wizard that guides new users through their
first Claw3D setup: welcome, prerequisites, gateway connection, agent
discovery, and a completion screen.

Architecture:

src/features/onboarding/ (new feature module):
  - types.ts: Step definitions, navigation helpers (getNextStep/getPrevStep)
  - useOnboardingState.ts: localStorage-backed persistence hook
  - index.ts: Barrel exports for clean imports
  - components/OnboardingWizard.tsx: Main wizard container with step
    navigation, progress bar, and modal overlay
  - components/WelcomeStep.tsx: Feature highlights grid
  - components/PrerequisitesStep.tsx: Checklist with links/commands
  - components/ConnectStep.tsx: Compact gateway connection form
  - components/AgentsStep.tsx: Agent discovery feedback
  - components/CompleteStep.tsx: Final screen with CTA

Design decisions:
  - Modular step system: new steps can be added by extending
    OnboardingStepId and registering a component in the switch
  - localStorage persistence: wizard shows once per browser, resettable
    from settings (future: wire into Studio settings API)
  - Connect step gates forward navigation: users cannot skip connection
  - Follows Claw3D conventions: feature-first module, no shared state
    pollution, Tailwind utility classes, lucide-react icons
  - Does NOT modify existing routes or components — zero-risk integration
    (parent wiring left to maintainer preference)

Integration guide (for maintainer):
  1. Import { OnboardingWizard, useOnboardingState } from the module
  2. Add useOnboardingState() to the root layout or agents page
  3. Render <OnboardingWizard /> when showOnboarding is true
  4. Pass gateway connection props from existing store

tests/unit/onboardingTypes.test.ts (13 tests):
  - Step structure validation, navigation helpers, ordering

tests/unit/onboardingState.test.ts (5 tests):
  - localStorage persistence, show/hide/reset lifecycle

Addresses #17

* fix(onboarding): wire wizard launch into office UI

Mount the onboarding wizard in OfficeScreen and add a settings action that can re-open it so the new-user flow is reachable and testable.

Made-with: Cursor

---------

Co-authored-by: Neo <neo@openclaw.ai>
Co-authored-by: iamlukethedev <lucas.guilherme@smartwayslfl.com>
2026-03-21 17:37:54 -05:00
robotica4us-collab ac30f71db0 fix(issue-5): add collision-aware pathfinding to Phaser office viewer (#24)
* fix(issue-5): add collision-aware pathfinding to Phaser office viewer

Agents in the Phaser office viewer previously moved in straight lines toward
zone anchors, ignoring walls, furniture, and collision geometry. This made
agents walk through rendered map obstacles.

Changes:

src/lib/office/pathfinding.ts (new):
  - Shared 2D A* pathfinding module for OfficeMap surfaces
  - Builds a nav grid from map objects (walls/furniture layers) and
    collision polygons with configurable cell size and padding
  - Diagonal corner-cutting prevention (checks both orthogonal neighbors)
  - Returns empty path on failure instead of raw destination fallback
  - Point-in-polygon rasterisation for collision polygon support
  - Intentionally placed in src/lib/office/ for reuse across office stacks

src/features/office/phaser/systems/AgentEffectsSystem.ts:
  - Computes A* waypoint paths when agent targets change
  - Follows waypoints sequentially instead of linear interpolation
  - Caches nav grid and invalidates on map identity change
  - Agents stay put when no valid path exists (no wall clipping)

tests/unit/officePathfinding.test.ts (new):
  - 12 unit tests covering grid construction, A* routing, corner-cutting
    prevention, collision polygon support, blocked-start recovery, and
    starter map integration

Fixes #5

* fix(test): remove unused NavGrid2D type import

---------

Co-authored-by: Neo <neo@openclaw.ai>
2026-03-21 17:23:11 -05:00
robotica4us-collab e24ed41532 fix(issue-4): replace hardcoded BLOCKING_TYPES with metadata-driven ITEM_METADATA (#20)
* fix(issue-4): add missing solid floor props to BLOCKING_TYPES

Audited all furniture types defined in furnitureDefaults.ts and
geometry.ts (ITEM_FOOTPRINT) against BLOCKING_TYPES in navigation.ts.

Added five previously missing solid floor props:
- water_cooler: freestanding floor appliance, agents pathfound through it
- server_terminal: floor-standing terminal in the server room
- dishwasher: floor appliance in the kitchen area
- easel: floor-standing art-room prop
- beanbag: floor seat large enough to obstruct walking paths

Also adds a unit test asserting every newly-added type is correctly
blocked in the nav grid, and that non-solid desk decorations (keyboard)
remain free.

* refactor(nav): replace hardcoded BLOCKING_TYPES with metadata-driven ITEM_METADATA

Previously, buildNavGrid() maintained a hardcoded BLOCKING_TYPES set in
navigation.ts. The issue #4 fix added the five missing solid props directly
to that set, but this approach is brittle — every new furniture type requires
a separate PR touching navigation.ts to stay correct.

This rework introduces ITEM_METADATA in geometry.ts (alongside the existing
ITEM_FOOTPRINT record) as the single source of truth for per-type navigation
properties:

  export const ITEM_METADATA: Record<string, { blocksNavigation: boolean }>

Each item type explicitly declares blocksNavigation: true/false. The five
props fixed in issue #4 (water_cooler, server_terminal, dishwasher, easel,
beanbag) retain their blocking status. Unknown types default to false, so
future decorative items never accidentally block navigation.

Changes:
- geometry.ts: add ITEM_METADATA export (64 type entries)
- navigation.ts: remove BLOCKING_TYPES set; add itemBlocksNavigation() helper
  that reads ITEM_METADATA[type]?.blocksNavigation ?? false; update buildNavGrid()
  to call it
- tests/unit/navigation.navBlockers.test.ts: retain original 5 solid-prop tests;
  add metadata-driven test suite covering: all blocking types from metadata,
  all non-blocking types from metadata, runtime-added type with blocksNavigation:true,
  and unknown-type safe fallback

All 10 tests pass; lint clean; only pre-existing TS2367 (issue #13) remains.

* test(navigation): add extended nav blocker tests (issue #4)

Additional tests for buildNavGrid and astar pathfinding:
- Adjacent blocking items create a continuous impassable wall
- Blocking item near grid edge/boundary causes no out-of-bounds errors
- Full pathfinding integration: astar routes AROUND a cabinet placed between
  start and end (not just that cells are blocked)
- desk_cubicle explicitly does NOT block — confirmed via ITEM_METADATA
- door explicitly does NOT block — agents must walk through doors

---------

Co-authored-by: Neo (subagent) <neo@openclaw.local>
2026-03-21 16:06:51 -05:00
robotica4us-collab 941612ab2d fix(issue-6): prevent A* diagonal corner-cutting through blocked cells (#19)
* fix(issue-6): prevent A* diagonal corner-cutting through blocked cells

The A* neighbor loop previously checked only whether the destination cell
was free. For diagonal moves this allows agents to clip through the corner
of a blocked cell — the two orthogonal neighbours (e.g. N and E for a NE
move) were never validated.

Fix: after confirming the diagonal destination is free, additionally check
both orthogonal intermediary cells. If either is blocked, the diagonal
expansion is skipped and the agent must route around the obstacle.

Adds three unit tests covering:
- a path that would clip a single corner (rejected after fix)
- a path through open space (diagonals still used freely)
- a path around a multi-cell wall segment (no cells in the wall visited)

* chore: remove unused imports from diagonal corner test (lint cleanup)

* test(navigation): add expanded diagonal corner-cutting tests (issue #6)

Additional tests for astar diagonal corner-cutting prevention:
- All 4 diagonal directions (NE, NW, SE, SW): block orthogonal neighbour,
  verify path avoids the blocked cell in each direction
- Both orthogonal sides blocked: verify no diagonal move is taken from start
- L-shaped wall: verify agent navigates around entire L without clipping any segment
- Dense grid stress test: maze-like layout verifying valid path found and no
  waypoint lands on a blocked cell

---------

Co-authored-by: Neo (subagent) <neo@openclaw.local>
2026-03-21 16:04:15 -05:00
Nix 533bcd9b3f fix(security): enforce access gate on all routes, not just /api/ (#42)
Co-authored-by: ThankNIXlater <267577058+ThankNIXlater@users.noreply.github.com>
2026-03-21 15:52:20 -05:00
Luke The Dev 6b5895dcfe Feature/avatar customization (#25)
* Avatar Customization + Update Agent Brain

* Bugfixes

---------

Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-20 23:17:30 -05:00
Luke The Dev 65c2b9cf85 Avatar Customization + Update Agent Brain (#23)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-20 23:05:14 -05:00
Tony Simons a5b0895dd8 Fix WS auth + gym release directive TypeScript error (#16)
* Fix WS auth: wire accessGate.allowUpgrade via verifyClient

The allowWs callback was never actually calling accessGate.allowUpgrade
during the WS handshake - the ws library passes (info) not (req), and
verifyClient must be set on the WebSocketServer constructor options.

Fix: pass verifyClient to WebSocketServer constructor and wrap
allowUpgrade to extract info.req.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix TypeScript error and add gym release directive support

Add "release" value to OfficeGymDirective type for symmetry with
OfficeQaDirective ("qa_lab" | "release"). Previously OfficeGymDirective
was only "gym" with no release state, making the "!== 'release'"
check in eventTriggers.ts dead code that TypeScript flagged as an
unintentional comparison.

Changes:
- deskDirectives.ts: add "release" to OfficeGymDirective type
- deskDirectives.ts: add gym release patterns to skill and command
  directive resolvers (e.g. "leave the gym", "done with skills")
- eventTriggers.ts: change !== "release" to === "gym" for clarity
  and consistency with reduceOfficeGymHoldState pattern

This fixes: https://github.com/iamlukethedev/Claw3D/issues/15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:00:58 -05:00
Tony Simons 3572499f5d docs: add .env.example for local development setup (#14)
Co-authored-by: Ozzy Clawsbourne <ozzy@openclaw.ai>
2026-03-20 00:22:38 -05:00
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00
Luke The Dev 5ea96b2650 Create CHANGELOG.md 2026-03-18 04:43:18 +00:00
Luke The Dev d4e4349dc0 Create CONTRIBUTING.md 2026-03-17 23:42:14 -05:00
Luke The Dev fc283406de Create ROADMAP.md 2026-03-17 23:40:51 -05:00
Luke The Dev 02a43199c1 Create SUPPORT.md 2026-03-17 23:40:08 -05:00
Luke The Dev b40ad44407 Create ARCHITECTURE.md 2026-03-17 23:38:53 -05:00
Luke The Dev 8c382cb362 Create CODE_OF_CONDUCT.MD 2026-03-17 23:37:48 -05:00
Luke The Dev 0520194216 Create LICENSE 2026-03-17 23:37:20 -05:00
Luke The Dev 19ba8618e2 Create SECURITY.md 2026-03-17 23:36:50 -05:00
Luke The Dev 4dd04eabbe Create VISION.md 2026-03-17 23:36:19 -05:00
Luke The Dev 1b9b97ff94 Create README.md 2026-03-17 23:35:36 -05:00
Luke The Dev 6e51d5c497 Create CODEOWNERS 2026-03-16 16:16:30 -05:00
Luke The Dev 31adda95b4 Create SECURITY.md 2026-03-16 16:15:46 -05:00
Luke The Dev ac07114883 Create FUNDING.yml 2026-03-16 15:47:34 -05:00
Luke The Dev a244895e8f Update config.yml 2026-03-16 15:37:46 -05:00
Luke The Dev c245925e9d Create config.yml 2026-03-16 15:36:57 -05:00
Luke The Dev cbeea9fb5e Update issue templates 2026-03-16 15:27:18 -05:00