mirror of
https://github.com/Ar9av/obsidian-wiki.git
synced 2026-09-14 20:36:34 +08:00
fix: close global writing profile review findings
This commit is contained in:
@@ -598,9 +598,9 @@ Every skill's setup section should read:
|
||||
|
||||
Before drafting or rewriting natural-language Markdown, resolve the global config directory with the XDG/legacy algorithm above, then read `<global config dir>/WRITING.md` when it exists. A missing or empty `WRITING.md` means there are no custom writing preferences. If that optional read fails, warn and continue with the default framework guidance.
|
||||
|
||||
Apply writing guidance from the current project and the resolved vault's `AGENTS.md` over global `WRITING.md` preferences. Framework invariants — including schema, provenance, safety, and operation-specific requirements — always take precedence over all writing preferences.
|
||||
The effective precedence is framework invariants > current task/skill requirements > current project `AGENTS.md` > vault `AGENTS.md` > global `WRITING.md`. Framework invariants include schema, provenance, and safety; operation-specific requirements remain authoritative for the current task. Unspecified project and vault rules are inherited from less-specific layers, and more specific same-topic rules win.
|
||||
|
||||
Writing preferences apply only to newly drafted or rewritten natural-language fields and body content. They do not change YAML frontmatter, JSON, structured logs, or pass-through content, which retain their required formats and source fidelity.
|
||||
Writing preferences apply only to newly drafted or rewritten natural-language fields and body content. This includes natural-language title and summary values in YAML frontmatter, but preferences cannot alter YAML syntax, required keys, structure, types, or machine-generated fields. JSON, structured logs, and pass-through content remain unchanged and retain their required formats and source fidelity.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ description: >
|
||||
|
||||
You are preserving knowledge from the current conversation as a permanent wiki note. The goal is to extract the *substance* — the knowledge itself — not a summary of what was said.
|
||||
|
||||
**Writing profile:** Before drafting or rewriting natural-language Markdown in any mode, read and apply the `Writing Profile Resolution` section in `llm-wiki/SKILL.md`. Framework schema, provenance, safety, and operation-specific requirements take precedence.
|
||||
`WRITING.md` preferences apply only to newly drafted or rewritten natural-language Markdown; preserve source content and structured records.
|
||||
|
||||
This skill has three modes:
|
||||
|
||||
- **Full mode (default)** — classify the content and write a finished, cross-linked wiki page directly into the right category. This is the rest of this document (Steps 1–7).
|
||||
@@ -99,9 +102,6 @@ After writing the derived correction, link the immutable source to the created/u
|
||||
|
||||
## Before You Start
|
||||
|
||||
**Writing profile:** Before drafting or rewriting natural-language Markdown, read and apply the `Writing Profile Resolution` section in `llm-wiki/SKILL.md`. Framework schema, provenance, safety, and operation-specific requirements take precedence.
|
||||
`WRITING.md` preferences apply only to newly drafted or rewritten natural-language Markdown; preserve source content and structured records.
|
||||
|
||||
1. **Resolve config** — follow the Config Resolution Protocol in `llm-wiki/SKILL.md` (inline `@name` override → walk up CWD for `.env` → global config → prompt setup). This gives `OBSIDIAN_VAULT_PATH` and `OBSIDIAN_LINK_FORMAT` (default: `wikilink`).
|
||||
2. Read `$OBSIDIAN_VAULT_PATH/index.md` to understand existing wiki content (avoid duplicates)
|
||||
3. Read `$OBSIDIAN_VAULT_PATH/hot.md` if it exists — it gives context on recent activity
|
||||
|
||||
+38
-13
@@ -62,26 +62,50 @@ If `.env` doesn't exist, create it from `.env.example`. Ask the user for:
|
||||
- When enabled: all new/updated pages land in `_staging/` first; run `/wiki-stage-commit` to review and promote them
|
||||
- `wiki-status` shows a "Staged writes pending" count when files are waiting
|
||||
|
||||
After resolving the global config directory using the Config Resolution Protocol in
|
||||
`.skills/llm-wiki/SKILL.md`, create the shared writing profile only when it does not
|
||||
After resolving config, assign the global config directory with the exact
|
||||
`obsidian_wiki_config_dir` algorithm from the Config Resolution Protocol in
|
||||
`.skills/llm-wiki/SKILL.md`. Create the shared writing profile only when it does not
|
||||
already exist. Preserve an existing `$GLOBAL_CONFIG_DIR/WRITING.md`; never overwrite it
|
||||
and do not ask additional writing-style questions.
|
||||
|
||||
Resolve the canonical template from `OBSIDIAN_WIKI_REPO` as follows:
|
||||
Use `OBSIDIAN_WIKI_REPO` when it was loaded from config. When it is absent, derive the
|
||||
absolute repository/data root from this loaded skill's absolute path, distinguishing the
|
||||
packaged `<root>/skills/wiki-setup/SKILL.md` layout from the source
|
||||
`<root>/.skills/wiki-setup/SKILL.md` layout. Then check both canonical template layouts:
|
||||
|
||||
- Packaged install: `$OBSIDIAN_WIKI_REPO/skills/llm-wiki/references/WRITING.md`
|
||||
- Source checkout: `$OBSIDIAN_WIKI_REPO/.skills/llm-wiki/references/WRITING.md`
|
||||
|
||||
Copy the first layout whose template exists:
|
||||
- Packaged install: `<root>/skills/llm-wiki/references/WRITING.md`
|
||||
- Source checkout: `<root>/.skills/llm-wiki/references/WRITING.md`
|
||||
|
||||
```bash
|
||||
GLOBAL_CONFIG_DIR="$(obsidian_wiki_config_dir)"
|
||||
mkdir -p "$GLOBAL_CONFIG_DIR"
|
||||
|
||||
SKILL_FILE="<absolute path of this loaded wiki-setup/SKILL.md>"
|
||||
SKILL_DIR="$(cd "$(dirname "$SKILL_FILE")" && pwd)"
|
||||
if [ -n "${OBSIDIAN_WIKI_REPO:-}" ]; then
|
||||
WIKI_ROOT="${OBSIDIAN_WIKI_REPO%/}"
|
||||
else
|
||||
case "$SKILL_DIR" in
|
||||
*/.skills/wiki-setup) WIKI_ROOT="${SKILL_DIR%/.skills/wiki-setup}" ;;
|
||||
*/skills/wiki-setup) WIKI_ROOT="${SKILL_DIR%/skills/wiki-setup}" ;;
|
||||
*) echo "Cannot derive writing-profile template root from $SKILL_DIR" >&2; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
WRITING_TEMPLATE=""
|
||||
for candidate in \
|
||||
"$WIKI_ROOT/skills/llm-wiki/references/WRITING.md" \
|
||||
"$WIKI_ROOT/.skills/llm-wiki/references/WRITING.md"
|
||||
do
|
||||
if [ -f "$candidate" ]; then
|
||||
WRITING_TEMPLATE="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ -n "$WRITING_TEMPLATE" ] || { echo "Writing profile template not found under $WIKI_ROOT" >&2; exit 1; }
|
||||
|
||||
WRITING_PROFILE="$GLOBAL_CONFIG_DIR/WRITING.md"
|
||||
if [ ! -e "$WRITING_PROFILE" ]; then
|
||||
if [ -e "$OBSIDIAN_WIKI_REPO/skills/llm-wiki/references/WRITING.md" ]; then
|
||||
WRITING_TEMPLATE="$OBSIDIAN_WIKI_REPO/skills/llm-wiki/references/WRITING.md"
|
||||
else
|
||||
WRITING_TEMPLATE="$OBSIDIAN_WIKI_REPO/.skills/llm-wiki/references/WRITING.md"
|
||||
fi
|
||||
cp "$WRITING_TEMPLATE" "$WRITING_PROFILE"
|
||||
fi
|
||||
```
|
||||
@@ -218,9 +242,10 @@ Run a quick sanity check:
|
||||
- [ ] `.env` has `OBSIDIAN_VAULT_PATH` set
|
||||
- [ ] `.obsidian/` directory exists
|
||||
- [ ] `_staging/` directory exists (required even when `WIKI_STAGED_WRITES` is not set — created on setup for future use)
|
||||
- [ ] `WRITING_PROFILE` exists at the resolved global config directory
|
||||
- [ ] Source directories (if configured) exist and are readable
|
||||
|
||||
Report the results and tell the user they can now:
|
||||
Report the results, including the resolved absolute `WRITING_PROFILE` path, and tell the user they can now:
|
||||
1. Open the vault in Obsidian (File → Open Vault → select the directory)
|
||||
2. Run `wiki-status` to see what's available to ingest
|
||||
3. Run `wiki-ingest` to add their first sources
|
||||
|
||||
@@ -297,6 +297,7 @@ echo "────────────────────────
|
||||
echo " Setup complete!"
|
||||
echo ""
|
||||
echo " Skills found: $SKILL_COUNT"
|
||||
echo " Writing profile: $WRITING_PROFILE"
|
||||
echo " Agents ready: Claude Code, Cursor, Windsurf, Gemini CLI, Antigravity,"
|
||||
echo " Codex, Hermes, OpenClaw, OpenCode, Aider, Factory Droid,"
|
||||
echo " Trae, Trae CN, Kiro, Pi, GitHub Copilot (CLI + VS Code Chat)"
|
||||
|
||||
@@ -26,6 +26,9 @@ class SetupShDelegatesToCliTest(unittest.TestCase):
|
||||
self.assertIn("WRITING.md", self.setup_sh)
|
||||
self.assertIn("llm-wiki/references/WRITING.md", self.setup_sh)
|
||||
|
||||
def test_reports_resolved_writing_profile_path(self) -> None:
|
||||
self.assertIn('Writing profile: $WRITING_PROFILE', self.setup_sh)
|
||||
|
||||
def test_calls_cli_module_not_a_standalone_git_flow(self) -> None:
|
||||
self.assertIn("obsidian_wiki.cli", self.setup_sh)
|
||||
|
||||
|
||||
@@ -34,6 +34,47 @@ def test_llm_wiki_defines_writing_profile_resolution() -> None:
|
||||
assert "AGENTS.md" in body
|
||||
|
||||
|
||||
def test_llm_wiki_defines_exact_precedence_and_inheritance() -> None:
|
||||
body = (ROOT / ".skills" / "llm-wiki" / "SKILL.md").read_text()
|
||||
assert (
|
||||
"framework invariants > current task/skill requirements > current project "
|
||||
"`AGENTS.md` > vault `AGENTS.md` > global `WRITING.md`"
|
||||
) in body
|
||||
assert "Unspecified project and vault rules are inherited" in body
|
||||
assert "more specific same-topic rules win" in body
|
||||
|
||||
|
||||
def test_llm_wiki_scopes_frontmatter_and_structured_content() -> None:
|
||||
body = (ROOT / ".skills" / "llm-wiki" / "SKILL.md").read_text()
|
||||
assert "natural-language title and summary values in YAML frontmatter" in body
|
||||
assert (
|
||||
"cannot alter YAML syntax, required keys, structure, types, or machine-generated fields"
|
||||
) in body
|
||||
assert "JSON, structured logs, and pass-through content remain unchanged" in body
|
||||
|
||||
|
||||
def test_wiki_setup_resolves_global_path_and_template_without_repo_config() -> None:
|
||||
body = (ROOT / ".skills" / "wiki-setup" / "SKILL.md").read_text()
|
||||
assert 'GLOBAL_CONFIG_DIR="$(obsidian_wiki_config_dir)"' in body
|
||||
assert 'SKILL_FILE="<absolute path of this loaded wiki-setup/SKILL.md>"' in body
|
||||
assert 'if [ -n "${OBSIDIAN_WIKI_REPO:-}" ]; then' in body
|
||||
assert "${SKILL_DIR%/skills/wiki-setup}" in body
|
||||
assert "${SKILL_DIR%/.skills/wiki-setup}" in body
|
||||
assert "/skills/llm-wiki/references/WRITING.md" in body
|
||||
assert "/.skills/llm-wiki/references/WRITING.md" in body
|
||||
|
||||
|
||||
def test_wiki_capture_applies_profile_before_every_mode() -> None:
|
||||
body = (ROOT / ".skills" / "wiki-capture" / "SKILL.md").read_text()
|
||||
hook = body.index("**Writing profile:**")
|
||||
for heading in (
|
||||
"## Quick Mode (`--quick`)",
|
||||
"## Correction Mode (`--correction`)",
|
||||
"## Full Mode",
|
||||
):
|
||||
assert hook < body.index(heading), heading
|
||||
|
||||
|
||||
def test_every_current_prose_writer_references_the_contract() -> None:
|
||||
for skill in REQUIRED_SKILLS:
|
||||
body = (ROOT / ".skills" / skill / "SKILL.md").read_text()
|
||||
|
||||
Reference in New Issue
Block a user