clone

a hermes agent plugin for openspec: tools for spec workflows and a dashboard tab for browsing changes and specs

chore: run the README tests as forge CI

cat committed 39afd28
forge attest runs .forge/ci in a clean worktree on this machine and signs
the result. It runs the three Node smoke tests and pytest from the README's
Tests section. pytest uses the Hermes Agent venv and tree (HERMES_AGENT,
default ~/.hermes/hermes-agent), because registry.py imports
hermes_constants from the host install.
commit
39afd284b045cdd738c1c827dd6e2f9c7d7766b1
parent
493b42cd95d2a30f967ede5a53eb22d1bd248fb9
author
cat <admin@dev.site>
ci
✓ passed in 2s, signed by cat
ci attestation
forge-attestation 1
type ci
commit 39afd284b045cdd738c1c827dd6e2f9c7d7766b1
tree 48d25cf4cd946acad4a3bea4f863ad3df31e6d31
script .forge/ci 276819a242ff4da25c6fc2edf1c71d91f48cfed3
result pass
exit 0
started 2026-10-17T22:58:27Z
duration 2s
runner (not shown here; refs/notes/ci has it)
system Darwin 25.5.0 arm64
env host
log sha256:0c5a535c33851f3f30d38372113955dc44f3f6659ea49fef0fd33b4c30b4b16b 889 lines
|[1] ESM structure
|  PASS  Has default export
|  PASS  Has named imports
|  PASS  No CommonJS exports
|  PASS  No require() calls
|
|[2] No raw JSX
|  PASS  No raw JSX outside jsx()/jsxs()
|
|[3] Allowed imports
|  PASS  Found 3 import(s)
|  PASS  No disallowed imports
|
|[4] Dynamic import: plugin identity
|  id=openspec register=true name="OpenSpec source registry + project surface — sources, changes, ideas, specs, and diffs."
|  PASS  Plugin id is "openspec"
|  PASS  Has register() function
|  PASS  Has name property
|  PASS  register() runs without error
|
|[5] Contributions: 2 registered
|  PASS  At least 2 contributions
|  PASS  Has ROUTES_AREA contribution
|  PASS  Has SIDEBAR_NAV_AREA contribution
|
|[6] Path and nav metadata
|  PASS  Route path "/openspec"
|  PASS  Sidebar nav label "OpenSpec"
|  PASS  Sidebar nav has codicon
|  PASS  Sidebar nav path /openspec
|
|[7] Render function
|  PASS  Route contribution has render()
|  PASS  render() returns a value
|  PASS  render() returns jsx descriptor
|
|[8] ctx.rest("/sources") invocation
|  PASS  Calls api.sources()
|  PASS  No direct fetch() calls
|  PASS  No direct fetch() calls
|  PASS  No window.fetch calls
|  PASS  api.sources() is in useQuery queryFn
|
|[9] Rendering transitions
|  PASS  Checks isLoading state
|  PASS  Checks error state
|  PASS  Uses Loader component
|  PASS  Uses ErrorState component
|  PASS  Uses EmptyState component
|
|[10] Source quality
|  PASS  No debug console.log
|  PASS  No TODO comments
|  PASS  No alert() calls
|  PASS  Plugin id is "openspec"
|  PASS  Plugin name is "OpenSpec"
|
|=== Results: 36 passed, 0 failed ===
|..................................................................       [100%]
|66 passed in 1.51s

Signature: good, cat

1 file changed, +9 -0
A.forge/ci9+++++++++
A .forge/ci +9 -0