Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 74 additions & 95 deletions .jaiph/docs_parity.jh
Original file line number Diff line number Diff line change
@@ -1,109 +1,103 @@
#!/usr/bin/env jaiph

const role = """
You are an expert technical writer for this project.
1. You are fluent in Markdown and can read TypeScript code and Bash
2. You write for a developer audience, focusing on clarity and practical
examples.
3. You are concise, specific, and value dense
4. Write so that a new developer to this codebase can understand your
writing, but don't assume your audience are experts in the topic/area you
are writing about.
5. You are good in formulating generic context and describing the problem
starting from the generic part, leaving the specific details for the
last step, once the audience is aware of the generic context and the
problem.
6. You write problem explanation and goals in a human approachable way,
while keeping details dense in separate sections, so both human and AI
7. Source code and docs/architecture.md are the single source of truth. You don't
trust the existing documentation blindly.
You are an expert technical writer for this project.
1. You are fluent in Markdown and can read TypeScript code and Bash
2. You write for a developer audience, focusing on clarity and practical
examples.
3. You are concise, specific, and value dense
4. Write so that a new developer to this codebase can understand your
writing, but don't assume your audience are experts in the topic/area you
are writing about.
5. You are good in formulating generic context and describing the problem
starting from the generic part, leaving the specific details for the
last step, once the audience is aware of the generic context and the
problem.
6. You write problem explanation and goals in a human approachable way,
while keeping details dense in separate sections, so both human and AI
7. Source code and docs/architecture.md are the single source of truth. You don't
trust the existing documentation blindly.
"""

script assert_newline_paths_are_files = ```
while IFS= read -r f; do
[ -z "$f" ] && continue
test -f "$f" || return 1
done <<< "$1"
while IFS= read -r f; do
f="${f#"${f%%[![:space:]]*}"}"
f="${f%"${f##*[![:space:]]}"}"
[ -z "$f" ] && continue
test -f "$f" || return 1
done <<< "$1"
```

rule docs_files_present(list) {
run assert_newline_paths_are_files(list)
}

script assert_worktree_clean_for_docs = ```
local current_changed_files
current_changed_files="$(
{
git diff --name-only --cached
git diff --name-only
git ls-files --others --exclude-standard
} | sort -u
)"
if [ -n "$current_changed_files" ]; then
echo "Refusing to run docs parity workflow on a dirty worktree." >&2
echo "Please commit, stash, or discard these files first:" >&2
echo "$current_changed_files" >&2
return 1
fi
local current_changed_files
current_changed_files="$(
{
git diff --name-only --cached
git diff --name-only
git ls-files --others --exclude-standard
} | sort -u
)"
if [ -n "$current_changed_files" ]; then
echo "Refusing to run docs parity workflow on a dirty worktree." >&2
echo "Please commit, stash, or discard these files first:" >&2
echo "$current_changed_files" >&2
return 1
fi
```

rule worktree_is_clean() {
run assert_worktree_clean_for_docs()
}

script assert_only_allowed_changed = ```
local allowed="$1"
local after_changed_files
after_changed_files="$(
{
git diff --name-only --cached
git diff --name-only
git ls-files --others --exclude-standard
} | sort -u
)"
while IFS= read -r changed_file; do
[ -z "$changed_file" ] && continue
if [[ $'\n'"$allowed"$'\n' == *$'\n'"$changed_file"$'\n'* ]]; then
continue
fi
echo "Unexpected file changed by docs prompt: $changed_file" >&2
return 1
done <<< "$after_changed_files"
local allowed="$1"
local after_changed_files
after_changed_files="$(
{
git diff --name-only --cached
git diff --name-only
git ls-files --others --exclude-standard
} | sort -u
)"
while IFS= read -r changed_file; do
[ -z "$changed_file" ] && continue
if [[ $'\n'"$allowed"$'\n' == *$'\n'"$changed_file"$'\n'* ]]; then
continue
fi
echo "Unexpected file changed by docs prompt: $changed_file" >&2
return 1
done <<< "$after_changed_files"
```

rule only_expected_docs_changed_after_prompt(allowed) {
run assert_only_allowed_changed(allowed)
}

script first_line_str = `printf '%s\n' "$1" | head -n 1`

script rest_lines_str = `printf '%s\n' "$1" | tail -n +2`

script list_docs_md_paths = ```
local out=""
local f
for f in docs/*.md; do
out="${out:+$out
}$f"
done
printf '%s\n' "$out"
local out="" f
for f in docs/*.md; do
if [ -z "$out" ]; then
out="$f"
else
out="$out"$'\n'"$f"
fi
done
printf '%s\n' "$out"
```

script build_allowed_paths_block = ```
local out="README.md
docs/index.html
docs/_layouts/docs.html
src/cli/shared/usage.ts"
local f
for f in docs/*.md; do
out="$out
$f"
done
printf '%s\n' "$out"
local out f
out="$(printf '%s\n' README.md docs/index.html docs/_layouts/docs.html src/cli/shared/usage.ts)"
for f in docs/*.md; do
out="$out"$'\n'"$f"
done
printf '%s\n' "$out"
```

script join_newline_args = `printf '%s\n' "$@"`

workflow update_from_task(taskDesc) {
prompt """
<role>
Expand All @@ -124,7 +118,7 @@ workflow update_from_task(taskDesc) {
The task description is:
${taskDesc}
</task>
"""
"""
}

workflow docs_page(path) {
Expand Down Expand Up @@ -206,31 +200,16 @@ workflow docs_overview(docPaths) {
"""
}

workflow process_docs_md_recursive(file, remaining) {
run docs_page(file)
if remaining == "" {
return
}
const next = run first_line_str(remaining)
const rest = run rest_lines_str(remaining)
run process_docs_md_recursive(next, rest)
}

workflow maybe_process_docs_md(first_doc, rest_docs) {
if first_doc == "" {
return
}
run process_docs_md_recursive(first_doc, rest_docs)
}

workflow default() {
ensure worktree_is_clean()
const allowed_list = run build_allowed_paths_block()
ensure docs_files_present(allowed_list)
const docs_md_list = run list_docs_md_paths()
const first_doc = run first_line_str(docs_md_list)
const rest_docs = run rest_lines_str(docs_md_list)
run maybe_process_docs_md(first_doc, rest_docs)
for path in docs_md_list {
if path != "" {
run docs_page(path)
}
}
run docs_overview(docs_md_list)
ensure only_expected_docs_changed_after_prompt(allowed_list)
}
Loading
Loading