Context
Issue #129 mixed multiple tracks and was closed after superseding the release-flow/docs portion into #184 (implemented by #185).
A remaining product risk is still present in current main:
DEFAULT_OUTPUT_DIR is still sketchi/png (packages/opencode-excalidraw/src/lib/output.ts)
resolveOutputPath is still unconstrained resolve(baseDir, path) (packages/opencode-excalidraw/src/lib/output.ts)
- model/tool-provided
outputPath can therefore write anywhere under repo-relative resolution (including root-level files)
- no automated tests currently cover session-scoped defaults or traversal/containment behavior for
outputPath
Goal
Make plugin artifact writes deterministic and safe by default:
- session-scoped storage under
/.sketchi/sessions/<sessionID>/png/...
- containment enforcement for tool-supplied
outputPath
- explicit and documented opt-out for power users
Scope
- Default output root migration
- Replace
sketchi/png default with /.sketchi/sessions/<sessionID>/png/....
- Ensure all diagram write paths (
diagram_from_prompt, diagram_tweak, diagram_restructure, diagram_to_png, diagram_grade) use the same policy.
- Containment enforcement
- By default, reject or normalize tool-provided
outputPath so writes cannot escape the session output root.
- Handle these cases explicitly:
- bare filename
- relative nested path
- absolute path
.. traversal attempts
- Add a clearly named explicit opt-out (env/config) for advanced users.
- Git ignore hygiene
- Ensure generated artifacts under
/.sketchi/** are ignored reliably (root .gitignore and/or nested .gitignore strategy).
- Automated coverage
- Add tests for:
- default session-scoped output path generation
outputPath containment for benign and malicious inputs
- opt-out behavior
- Keep plugin CI gates exercising these tests.
- Docs consistency
- Update
packages/opencode-excalidraw/README.md with the new default output policy and opt-out behavior.
Non-Goals
Acceptance Criteria
- Default diagram outputs no longer target
/sketchi/png; they are session-scoped under /.sketchi/sessions/<sessionID>/png.
- Default behavior prevents
outputPath escaping the session root.
- Opt-out exists, is explicit, and documented.
- Tests fail before and pass after the change for traversal/containment scenarios.
- README reflects actual output path behavior.
Supersedes/Traceability
Context
Issue #129 mixed multiple tracks and was closed after superseding the release-flow/docs portion into #184 (implemented by #185).
A remaining product risk is still present in current
main:DEFAULT_OUTPUT_DIRis stillsketchi/png(packages/opencode-excalidraw/src/lib/output.ts)resolveOutputPathis still unconstrainedresolve(baseDir, path)(packages/opencode-excalidraw/src/lib/output.ts)outputPathcan therefore write anywhere under repo-relative resolution (including root-level files)outputPathGoal
Make plugin artifact writes deterministic and safe by default:
/.sketchi/sessions/<sessionID>/png/...outputPathScope
sketchi/pngdefault with/.sketchi/sessions/<sessionID>/png/....diagram_from_prompt,diagram_tweak,diagram_restructure,diagram_to_png,diagram_grade) use the same policy.outputPathso writes cannot escape the session output root...traversal attempts/.sketchi/**are ignored reliably (root.gitignoreand/or nested.gitignorestrategy).outputPathcontainment for benign and malicious inputspackages/opencode-excalidraw/README.mdwith the new default output policy and opt-out behavior.Non-Goals
next/latest) (covered by Ensure opencode prerelease (next) publishes on every plugin iteration #184/ci: publish opencode next on every iteration #185)Acceptance Criteria
/sketchi/png; they are session-scoped under/.sketchi/sessions/<sessionID>/png.outputPathescaping the session root.Supersedes/Traceability