Commit graph

2 commits

Author SHA1 Message Date
defed434cc feat(form): pre-flight Submit gate + cap-toast on 403
Two changes to the form tool's submit path:

  - Submit button hides when /.profile/access?path=<submission dir>
    reports no 'c' verb. The form-status line surfaces a short
    explanation so the user knows why the button disappeared.
  - 403 on POST routes through zddc.cap.handleForbidden, which
    renders an error toast naming the missing verb and offers
    Elevate when the path-scoped view reports an elevation grant
    covering it. The existing "You are not allowed to submit here"
    status line still appears as the in-form indicator.

Also guards shared/cap.js's fetchAccess against file:// URLs —
calling fetch() on a file:// page logs a browser-level error that
shows up as test-runner noise. Short-circuiting to null lets
offline tools (browse on a picked folder, form opened standalone
from a file URL) silently degrade to "no path-scoped info" and
fall back to whatever existing gate they had.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 08:50:49 -05:00
b5b3c92905 feat(shared): cap.js client helpers for permission gating
Three small helpers under window.zddc.cap, wired into every tool's
build:

  cap.at(path)               — Promise<AccessView|null>. Fetches
                               /.profile/access?path=<urlpath> and
                               memoises per-path for the session.
                               Used by tools to gate top-of-page
                               affordances on path_verbs / path_is_admin
                               / path_can_elevate_grant.
  cap.has(node, verb)        — boolean. Reads the listing entry's
                               verbs string for the named verb.
                               Falls back to node.writable for 'w'
                               when verbs is absent (offline FS-API
                               listings or pre-promotion clients).
  cap.handleForbidden(resp,  — parses a 403 response's JSON body for
                  opts)        missing_verb and renders an error
                               toast. When opts.path is supplied AND
                               the path-scoped access view reports
                               path_can_elevate_grant covering the
                               missing verb, the toast appends an
                               "Elevate" button that flips the
                               elevation cookie and reloads.

Browse loader.js + tree.js carry the new verbs field through to the
node objects so context-menu gating can call cap.has(node, 'w'|'d')
without changing the legacy node.writable contract. New CSS rule
.zddc-toast__action styles the inline Elevate button.

Concatenation order: cap.js comes after toast.js + elevation.js so
the dependencies (window.zddc.toast, window.zddc.elevation) are
present at module-load time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 08:42:05 -05:00