feat(shapes): a component file is a candidate shape in its own right (milestone 439 step 5)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 54s
CI & Build / Build & push image (push) Canceled after 0s
CI & Build / Python tests (push) Canceled after 1m42s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 54s
CI & Build / Build & push image (push) Canceled after 0s
CI & Build / Python tests (push) Canceled after 1m42s
A single-file component defines `.card`, `.title` and a `Props`, never anything named after itself — so the ledger could not hold "StatusChip is canon" and could not say a new card was built where one already existed. - coverage.is_file_unit: a file that RENDERS (its markup names classes, or it opens a <script>/<template>/<style> block) and defines nothing named after its stem gets one `file` row. Structural, not a framework list: Svelte and Vue components qualify, a TSX component already has its function's row, a module is accounted for by its definitions. Emitting every file would have put every module of every project in the todo at once. - No body fingerprint on file rows, so an edit never re-asks a judgment. - `file` is its own form and family; derive grouping skips it (`index`, `+page` repeat by convention). Divergence buckets it on its own, so a new component where a component canon dominates is a fair question. - mark_canonicals: a snippet recorded at a path with no symbol makes that file row canonical; it still covers no definition inside. - The write hooks apply the same test before noting a new file for the end-of-turn question. Plugin version minted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "scribe",
|
||||
"description": "Scribe for Claude Code: connects the scribe MCP server, adds the hooks that deliver live project state and relevant records at the right moment, ships the shared client-neutral Scribe skills (using-scribe, writing-plans, reporting-back, systematic-debugging, verification, brainstorming, reusing-code, shape-accounting), and syncs your saved Scribe Processes as skills (/scribe:sync).",
|
||||
"version": "2026.10.01.1242",
|
||||
"version": "2026.10.01.1245",
|
||||
"author": {
|
||||
"name": "Bryan Van Deusen"
|
||||
},
|
||||
|
||||
@@ -141,7 +141,7 @@ while IFS= read -r rel_path; do
|
||||
names=$(printf '%s' "$code" | scribe_defs | sort -u | head -12 || true)
|
||||
# What this write defined, for the end-of-turn question (milestone 439) —
|
||||
# recorded before the arms below, which skip a write that defines nothing.
|
||||
printf '%s\n' "$names" | scribe_written_append "$safe_sid" "$rel_path" "$fresh"
|
||||
printf '%s\n' "$names" | scribe_written_append "$safe_sid" "$rel_path" "$fresh" "$code"
|
||||
# Nothing DEFINED in what was written (prose, data, a call-site edit) →
|
||||
# nothing to say; the arms are about shapes.
|
||||
[ -n "$names" ] || continue
|
||||
|
||||
@@ -1163,22 +1163,32 @@ SCRIBE_LEDGER_DIRS="scribe-priorart scribe-autoinject"
|
||||
# end of the turn (scribe_shape_check.sh). Its own file — one file, one
|
||||
# question (lesson #4226) — under the prior-art directory, so the session
|
||||
# clear above already sweeps it. Read `kind<TAB>name` lines on stdin (the
|
||||
# scribe_defs format). A NEW file adds one `file` line named by its stem: a
|
||||
# component, module or package file is a candidate in its own right, in any
|
||||
# language, without a framework rule saying so.
|
||||
# scribe_defs format).
|
||||
#
|
||||
# A NEW file that is a unit in its own right adds one `file` line named by its
|
||||
# stem — the same test the server's sync applies (coverage.is_file_unit): it
|
||||
# RENDERS (markup names classes, or it opens a <script>/<template>/<style>
|
||||
# block) and nothing inside it is named after it. That is a component in any
|
||||
# framework, without a list of frameworks.
|
||||
# $1 session id (already made filename-safe) $2 repo-relative path
|
||||
# $3 "new" when the file did not exist before this write
|
||||
# $4 the code written (to test whether the file renders)
|
||||
scribe_written_append() {
|
||||
local sid="$1" rel="$2" fresh="${3:-}" dir stem
|
||||
local sid="$1" rel="$2" fresh="${3:-}" code="${4:-}" dir stem names
|
||||
if [ -z "$sid" ] || [ -z "$rel" ]; then cat >/dev/null; return 0; fi
|
||||
dir="${TMPDIR:-/tmp}/scribe-priorart"
|
||||
mkdir -p "$dir" 2>/dev/null || true
|
||||
names=$(cat)
|
||||
{
|
||||
if [ "$fresh" = "new" ]; then
|
||||
stem=${rel##*/}; stem=${stem%.*}
|
||||
[ -n "$stem" ] && printf '%s\tfile\t%s\n' "$rel" "$stem"
|
||||
if [ -n "$stem" ] \
|
||||
&& ! printf '%s\n' "$names" | awk -F'\t' -v s="$stem" '$1 == "sym" && $2 == s { f = 1 } END { exit !f }' \
|
||||
&& printf '%s\n' "$code" | grep -qE '^[[:space:]]*<(script|template|style)([[:space:]>]|$)|(class|className)[[:space:]]*='; then
|
||||
printf '%s\tfile\t%s\n' "$rel" "$stem"
|
||||
fi
|
||||
fi
|
||||
awk -F'\t' -v p="$rel" 'NF >= 2 && ($1 == "sym" || $1 == "css") && $2 != "" { printf "%s\t%s\t%s\n", p, $1, $2 }'
|
||||
printf '%s\n' "$names" | awk -F'\t' -v p="$rel" 'NF >= 2 && ($1 == "sym" || $1 == "css") && $2 != "" { printf "%s\t%s\t%s\n", p, $1, $2 }'
|
||||
} >> "$dir/${sid}.written.ids" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -202,12 +202,13 @@ rule_exclude_q=""
|
||||
if [ -n "$session_id" ]; then
|
||||
safe_sid=$(printf '%s' "$session_id" | tr -c 'A-Za-z0-9._-' '_')
|
||||
# What this write defined, for the end-of-turn question (milestone 439). A
|
||||
# Write onto a path that does not exist yet creates a file — a candidate in
|
||||
# its own right. Written before any server call: the ask at the end of the
|
||||
# turn must not depend on this write's hint having been answered.
|
||||
# Write onto a path that does not exist yet creates a file, which may be a
|
||||
# unit in its own right (see scribe_written_append). Written before any
|
||||
# server call: the ask at the end of the turn must not depend on this
|
||||
# write's hint having been answered.
|
||||
fresh=""
|
||||
[ -e "$file_path" ] || fresh="new"
|
||||
printf '%s\n' "$shapes" | scribe_written_append "$safe_sid" "$rel_path" "$fresh"
|
||||
printf '%s\n' "$shapes" | scribe_written_append "$safe_sid" "$rel_path" "$fresh" "$code"
|
||||
idfile="$state_dir/${safe_sid}.ids"
|
||||
syncfile="$state_dir/${safe_sid}.sync.ids"
|
||||
derivefile="$state_dir/${safe_sid}.derive.ids"
|
||||
|
||||
Reference in New Issue
Block a user