원클릭으로
apply-fix
Apply an approved Obelus plan file to the paper source.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Apply an approved Obelus plan file to the paper source.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Read the whole paper, treat the bundle's marks as a unified editorial brief, emit a holistic minimal-diff plan as JSON.
Apply the marks in an Obelus bundle as a revision — minimal-diff edits to this paper's source.
Read an already-emitted Obelus plan and propose additional improvement blocks the reviewer's marks (and the rigorous sweeps) did not cover.
One-turn drafter — read a writer-mode bundle once, read the whole paper, draft a holistic minimal-diff plan. No subagent, no impact / coherence sweeps.
Turn an Obelus bundle's marks into a structured Markdown review — a reviewer's letter to the editor.
Read an Obelus compile-error bundle, make the minimal source edits needed to clear the compiler errors, and stop. The desktop re-runs the compiler to verify.
| name | apply-fix |
| description | Apply an approved Obelus plan file to the paper source. |
| argument-hint | <plan-path> [--dry-run] |
| disable-model-invocation | true |
| allowed-tools | Read Edit Write Bash |
Read an already-written Obelus plan file and apply each block as a single-hunk edit on the paper source, then write a summary file under the resolved workspace prefix. The user must invoke this skill by name.
The workspace prefix is $OBELUS_WORKSPACE_DIR: an absolute path the caller hands you, which the Obelus desktop sets to a per-project subdirectory under app-data and includes in the spawn invocation. There is no .obelus/ fallback — the plugin must never write into the user's paper repo.
If the spawn invocation does not give you a value for $OBELUS_WORKSPACE_DIR, stop and refuse with:
This skill requires
$OBELUS_WORKSPACE_DIRto be set to an absolute writable directory outside the paper repo. The Obelus desktop sets it automatically; standalone CLI users should export it before invoking the plugin, e.g.:export OBELUS_WORKSPACE_DIR="$HOME/.local/share/obelus/runs/$(date +%Y%m%d-%H%M%S)" mkdir -p "$OBELUS_WORKSPACE_DIR" claude --add-dir "$OBELUS_WORKSPACE_DIR" /obelus:apply-fix <plan-path>
<plan-path> — absolute path to the plan file produced by apply-revision / plan-fix / plan-writer-fast, under $OBELUS_WORKSPACE_DIR. Either the JSON contract (<workspace>/plan-<iso>.json) or the desktop-projected Markdown (<workspace>/plan-<iso>.md) is accepted; when given the .md, this skill still loads the sibling .json for format/entrypoint and the structured block list.--dry-run (optional, default off) — print the patches that would be applied, write the summary file, but do not call Edit on any source. Useful before a destructive run on a dirty working tree.Every file in a plan block must resolve to a location inside the current paper-repo root (the working directory in which this skill is invoked). That is the only tree this skill is authorized to apply edits in.
A block target path is admissible iff all of the following hold:
/, no C: / D: / etc. drive prefix),.. segment,\),If any block file fails those checks, skip the block and record it as refused (out of scope). Do not call Edit or Write for it.
The artifacts this skill itself writes — the apply summary apply-<iso>.md and (for Typst) the rendered preview rendered/<entrypoint-basename>.pdf — land under $OBELUS_WORKSPACE_DIR, which is outside the repo root by design. The Path scope rules above apply to plan-block targets (paper source), not to these workspace artifacts. Writing to $OBELUS_WORKSPACE_DIR/apply-<iso>.md and $OBELUS_WORKSPACE_DIR/rendered/<file>.pdf is allowed and required.
A plan block that names file: ../../etc/hosts resolves outside the repo root. The block is skipped, and the summary records:
Refused (out of scope): 1
- 550e8400-...-446655440003 → ../../etc/hosts (escapes repo root)
The user sees the named path in the summary so they can audit the bundle that produced it. Do not silently drop it.
Verify target paths. Before any Read/Edit/Write, walk the parsed blocks and check every file against the Path scope rules above. A single refused block does not abort the run — skip it and continue — but an Edit/Write tool call for a refused path is a bug, never execute one.
Read the plan at <plan-path>. The JSON is the contract — when <plan-path> ends in .json, parse blocks[] directly and treat each entry's annotationIds[0] as the heading id (record the rest for the summary). When <plan-path> ends in .md, also Read the sibling .json next to it and use the JSON's structured block list as ground truth (the .md is a projection, not the contract). Each block's working shape is { annotationId, file, patch (@@ -L,N +L,N @@\n- before\n+ after\n), ambiguous, emptyReason }.
For each block, in order:
file failed step 0, skip. Record as refused.ambiguous: true, skip. Record as skipped.edit: none (e.g. praise blocks), skip. Record as recorded.--dry-run was passed, print the would-be patch (@@ -L,N +L,N @@ plus the - before / + after lines) and continue without calling Edit.before text still matches at the recorded span (source may have changed since the plan was written), and apply it with the Edit tool. If before no longer matches, skip and record as stale.Do not batch edits. One block, one Edit call. If a block fails to apply, record the reason and continue to the next.
Compile verify (Typst only). Skip this step entirely on --dry-run. Otherwise, read the plan JSON's top-level format and entrypoint fields (the same JSON loaded in step 1). If format === "typst", entrypoint !== "", and at least one block was applied in step 2, run:
typst compile <entrypoint> $OBELUS_WORKSPACE_DIR/rendered/<entrypoint-basename>.pdf --root .
via Bash. First check typst --version — if that command fails (non-zero exit or "command not found"), skip compile verify entirely and record Compile verify: skipped (typst not on PATH) in the summary. Do not treat typst's absence as an apply failure; the edits still stand.
On non-zero exit from typst compile, parse the first 5 errors from stderr. The Typst error format is <file>:<line>:<col>: error: <message>, sometimes followed by source context lines and a caret — ignore anything after the error: line until you reach the next <file>:<line>:<col>: header. For each error, Read the affected file around the line, propose a minimal Edit that resolves it (typical cases: a @key or #cite(<key>) referencing a missing bib entry → rewrite to #emph[(citation needed)]; unbalanced braces → restore them; unknown identifier → restore the name from the before side of the plan block that introduced it). Then rerun typst compile exactly as above.
Retry cap: 2. After the second failed retry, stop attempting fixes and move on to step 5. Record unresolved errors in the summary as Compile errors (unresolved) — do NOT revert earlier edits; the bytes are valid, only the compile is broken, and the user should see what landed.
Write a summary to $OBELUS_WORKSPACE_DIR/apply-<iso-timestamp>.md (compact UTC: YYYYMMDD-HHmmss, e.g. 20260423-143012):
Mode: applied or Mode: dry-runApplied: <n> — list with file:line and the annotation idRefused (out of scope): <n> — list with annotation id and the offending path, parenthetical reasonSkipped (ambiguous): <n> — list with annotation idSkipped (stale): <n> — list with annotation id and the file:line we readRecorded (praise / no-op): <n> — list with annotation idCompile fixes applied: <n> — list with file:line — before → after per follow-up Edit from step 4. Emit even when zero — Compile fixes applied: 0 is a fact.Compile errors (unresolved): <n> — list with file:line — message per error left after the retry cap. Omit the section entirely when zero (distinct from "we didn't run" — which prints as the Compile verify: skipped (…) line under Mode:).The summary path is a workspace artifact (see the Workspace artifacts clause above), which is why it is safe to Write.
Final marker line. Print the summary counts to the user, then print exactly one line on stdout in this form, with nothing else on the line:
OBELUS_WROTE: $OBELUS_WORKSPACE_DIR/apply-<iso-timestamp>.md
This is always an absolute path. Same convention apply-revision and write-review use; the desktop scans stdout for it as a fallback locator.
ambiguous.apply-revision.OBELUS_WROTE: marker.typst compile if typst --version fails — record Compile verify: skipped (typst not on PATH) and return normally.typst compile more than twice. Two attempts cap cascading self-edits; beyond that, report rather than fix.Plan at <workspace>/plan-20260423-143012.md with three blocks (one valid, one out-of-scope, one praise). With --dry-run:
[stdout]
Would apply (1):
main.tex:142 — elaborate (550e8400-...-440001)
@@ -142,1 +142,1 @@
- as shown by Vaswani et al.
+ as shown by Vaswani et al.~\cite{TODO}
Refused (1):
../../etc/hosts — escapes repo root (550e8400-...-440003)
Recorded (1):
conclusion.tex:88 — praise (550e8400-...-440002)
OBELUS_WROTE: <workspace>/apply-20260423-143012.md
No Edit tool calls happened. The summary file describes the planned actions so the user can review before rerunning without --dry-run. In a real run, every <workspace>/... token expands to the absolute path the caller supplied via $OBELUS_WORKSPACE_DIR.
Plan's companion JSON sets format: "typst", entrypoint: "main.typ". Step 2 applies one elaborate edit at main.typ:42, inserting a stale @smith cite that no .bib entry defines. The plan itself was valid; the source tree shifted under it (a reviewer renamed the bib key after the plan was written). Step 4 runs:
$ typst --version
typst 0.12.0
$ typst compile main.typ "<workspace>/rendered/main.pdf" --root .
error: label `<smith>` does not exist in the document
┌─ main.typ:42:31
The skill Reads main.typ:40-44, confirms @smith on line 42 is the offending token, and issues an Edit replacing @smith with #emph[(citation needed)]. Rerun:
$ typst compile main.typ "<workspace>/rendered/main.pdf" --root .
$ echo $?
0
Summary:
Mode: applied
Applied: 1
main.typ:42 — elaborate (550e8400-...-440042)
Refused (out of scope): 0
Skipped (ambiguous): 0
Skipped (stale): 0
Recorded (praise / no-op): 0
Compile fixes applied: 1
main.typ:42 — @smith → #emph[(citation needed)]
Then the marker (always an absolute path):
OBELUS_WROTE: <workspace>/apply-20260423-143012.md
If the second retry had also failed, the summary would instead carry:
Compile fixes applied: 2
main.typ:42 — @smith → #emph[(citation needed)]
main.typ:42 — #emph[(citation needed)] → #emph((citation needed))
Compile errors (unresolved): 1
main.typ:42 — expected content, found closing paren
and apply-fix still prints its OBELUS_WROTE: marker. The user sees what landed, what was tried, and what is still broken.
$OBELUS_WORKSPACE_DIR/apply-<iso>.md summary exists on disk.format === "typst", the summary contains either a Compile fixes applied: <n> line (runs that attempted compile verify) or a Compile verify: skipped (…) line (typst-not-on-PATH path). Never both.OBELUS_WROTE: $OBELUS_WORKSPACE_DIR/apply-<iso>.md with nothing else on it.