@appchy/jarvis 0.1.67 → 0.1.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +1 -1
- package/harness/harness/safety.py +47 -12
- package/harness/test_work.py +35 -0
- package/package.json +5 -5
package/dist/bin.js
CHANGED
|
@@ -10115,7 +10115,7 @@ import { createRequire as createRequire2 } from "module";
|
|
|
10115
10115
|
var _require = createRequire2(import.meta.url);
|
|
10116
10116
|
var VERSION2 = _require("../package.json").version ?? "0.0.0";
|
|
10117
10117
|
var IS_DEV = String(_require("../package.json").name ?? "").endsWith("-dev");
|
|
10118
|
-
var SHA = "
|
|
10118
|
+
var SHA = "ac6ee80";
|
|
10119
10119
|
var BUILT = "2026-09-10";
|
|
10120
10120
|
var BUILD = SHA ?? "source";
|
|
10121
10121
|
var BUILD_LABEL = `${SHA ? `${VERSION2} (${SHA}${BUILT ? ` ${BUILT}` : ""})` : `${VERSION2} (source)`}${IS_DEV ? " \u2014 development build" : ""}`;
|
|
@@ -285,12 +285,46 @@ def cmd_doctor(args) -> int:
|
|
|
285
285
|
from .align import _foreign_qualifier
|
|
286
286
|
foreign = _foreign_qualifier()
|
|
287
287
|
other = re.compile(r"\b([A-Z][A-Z0-9]{0,3})-\d+\b")
|
|
288
|
+
# A LEDGER declares itself by defining entries: `### J-52 — …`, `## S-1. …`.
|
|
289
|
+
# Prose never does. That distinction is the whole check — without it the
|
|
290
|
+
# pattern above reads `SHA-256`, `JP-8000` and `AUTO-3` as citations, which
|
|
291
|
+
# on one audio repo was 53 of its reported strays and no configuration
|
|
292
|
+
# could have silenced them honestly: there is no repo called SHA, and
|
|
293
|
+
# calling SHA a ledger to go green is the lie the check exists to prevent.
|
|
294
|
+
#
|
|
295
|
+
# Definitions are looked for in the board AND in the standards file the
|
|
296
|
+
# spine names, because a repo's second ledger usually lives there rather
|
|
297
|
+
# than under `work/`. An unconfigured install is still caught, which is what
|
|
298
|
+
# this check is FOR: its rules are headings, so its prefix is declared here
|
|
299
|
+
# and reported as unmatched.
|
|
300
|
+
# The separator is load-bearing, not decoration. Every ledger in every repo
|
|
301
|
+
# here writes `### J-52 — Title` or `## S-1. Title`; a heading that merely
|
|
302
|
+
# TALKS about an id writes `### AUTO-4 ARRIVED AS A DERIVATION`, with a
|
|
303
|
+
# bare space. Without this, one such heading in one brief was enough to
|
|
304
|
+
# promote a synth's model number to a ledger.
|
|
305
|
+
defines = re.compile(r"^#{1,6}\s+([A-Z][A-Z0-9]{0,3})-\d+(?:\.|\s+[\u2014\u2013-])")
|
|
288
306
|
allowed = {cfg["ids"]["prefix"], *cfg["ids"]["recognised"], "AC", "B"}
|
|
307
|
+
|
|
308
|
+
board = list(root.rglob("*.md"))
|
|
309
|
+
spine = cfg.get("spine", {}).get("standards")
|
|
310
|
+
elsewhere = [repo / spine] if spine and (repo / spine).is_file() else []
|
|
311
|
+
|
|
312
|
+
declared, lines_by_doc = set(), {}
|
|
313
|
+
for md in board + elsewhere:
|
|
314
|
+
lines = md.read_text(errors="ignore").splitlines()
|
|
315
|
+
if md in board:
|
|
316
|
+
lines_by_doc[md] = lines
|
|
317
|
+
for line in lines:
|
|
318
|
+
d = defines.match(line)
|
|
319
|
+
if d:
|
|
320
|
+
declared.add(d.group(1))
|
|
321
|
+
|
|
289
322
|
stray = {}
|
|
290
|
-
for
|
|
291
|
-
for line in
|
|
323
|
+
for lines in lines_by_doc.values():
|
|
324
|
+
for line in lines:
|
|
292
325
|
for m in other.finditer(line):
|
|
293
|
-
if m.group(1) in allowed or
|
|
326
|
+
if (m.group(1) in allowed or m.group(1) not in declared
|
|
327
|
+
or foreign.search(line[:m.start()])):
|
|
294
328
|
continue
|
|
295
329
|
stray.setdefault(m.group(1), 0)
|
|
296
330
|
stray[m.group(1)] += 1
|
|
@@ -298,15 +332,16 @@ def cmd_doctor(args) -> int:
|
|
|
298
332
|
top = ", ".join(f"{k}-nn x{v}" for k, v in
|
|
299
333
|
sorted(stray.items(), key=lambda kv: -kv[1])[:4])
|
|
300
334
|
warn("ids", f"{sum(stray.values())} id(s) match no configured prefix "
|
|
301
|
-
f"({top}).
|
|
302
|
-
f"
|
|
303
|
-
f"
|
|
304
|
-
f"
|
|
305
|
-
f"
|
|
306
|
-
f"
|
|
307
|
-
f"
|
|
308
|
-
f"
|
|
309
|
-
f"
|
|
335
|
+
f"({top}). Each of those prefixes DEFINES entries "
|
|
336
|
+
f"somewhere in this repo, so they are ledgers rather than "
|
|
337
|
+
f"prose, and three readings remain. If one IS this repo's "
|
|
338
|
+
f"ledger letter, set ids.prefix — every check is reading "
|
|
339
|
+
f"the wrong dialect until you do. If this repo keeps a "
|
|
340
|
+
f"SECOND ledger of its own — standards beside rules, say "
|
|
341
|
+
f"— add its letter to ids.recognised: it is read as native "
|
|
342
|
+
f"and never generated. If a sibling repo's ledger is "
|
|
343
|
+
f"quoted here in full, add that repo to ids.foreign, which "
|
|
344
|
+
f"excuses it where the repo is named alongside.")
|
|
310
345
|
else:
|
|
311
346
|
ok("ids", f"every id matches a configured prefix")
|
|
312
347
|
|
package/harness/test_work.py
CHANGED
|
@@ -1778,6 +1778,41 @@ def test_doctor_passes_a_degraded_but_legal_install_and_fails_a_real_break():
|
|
|
1778
1778
|
assert f"{tree.cli()} init" in out.getvalue()
|
|
1779
1779
|
|
|
1780
1780
|
|
|
1781
|
+
def test_doctor_reads_a_ledger_as_an_id_and_leaves_prose_alone():
|
|
1782
|
+
import io, contextlib
|
|
1783
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
1784
|
+
root = _initialised(tmp)
|
|
1785
|
+
|
|
1786
|
+
# Prose that merely LOOKS like a citation. A hash algorithm, a synth's model
|
|
1787
|
+
# number, and a heading that talks about an id rather than defining one — all
|
|
1788
|
+
# measured on a real audio repo, where they were 53 reported strays that no
|
|
1789
|
+
# configuration could have silenced honestly.
|
|
1790
|
+
(root / "product" / "notes.md").write_text(
|
|
1791
|
+
"# Notes\n\n"
|
|
1792
|
+
"An identical SHA-256 over 10,000 bytes, and the JP-8000 supersaw.\n\n"
|
|
1793
|
+
"### AUTO-4 ARRIVED AS A DERIVATION RATHER THAN A TOLERANCE\n\n"
|
|
1794
|
+
"Their `AUTO-1..4` clause families.\n"
|
|
1795
|
+
)
|
|
1796
|
+
with contextlib.redirect_stdout(io.StringIO()) as out:
|
|
1797
|
+
assert safety.cmd_doctor({"project_root": tmp}) == 0
|
|
1798
|
+
said = out.getvalue()
|
|
1799
|
+
for prose in ("SHA-nn", "JP-nn", "AUTO-nn"):
|
|
1800
|
+
assert prose not in said, f"{prose} is prose, not a citation"
|
|
1801
|
+
assert "every id matches a configured prefix" in said
|
|
1802
|
+
|
|
1803
|
+
# An UNCONFIGURED install is the thing this check exists to catch, and it still
|
|
1804
|
+
# is: a ledger declares itself by DEFINING entries, and those are headings.
|
|
1805
|
+
(root / "architecture" / "camera.md").write_text(
|
|
1806
|
+
"---\ntype: system\n---\n\n# Camera\n\n"
|
|
1807
|
+
"### Q-1 — The camera never settles a shot alone\n\n"
|
|
1808
|
+
"### Q-2 — A frame is stamped once\n"
|
|
1809
|
+
)
|
|
1810
|
+
with contextlib.redirect_stdout(io.StringIO()) as out:
|
|
1811
|
+
assert safety.cmd_doctor({"project_root": tmp}) == 0
|
|
1812
|
+
said = out.getvalue()
|
|
1813
|
+
assert "Q-nn" in said, "an unconfigured ledger must still be reported"
|
|
1814
|
+
|
|
1815
|
+
|
|
1781
1816
|
def test_align_does_not_read_the_harnesss_own_modules_or_suite():
|
|
1782
1817
|
# AC-07, moved here from `config-seam`: the shipped suite's fixture ids must not
|
|
1783
1818
|
# resolve against a CONSUMER's ledger. "The payload lives in the plugin cache so
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appchy/jarvis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.68",
|
|
4
4
|
"description": "Jarvis — local AI coding assistant CLI",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -56,17 +56,17 @@
|
|
|
56
56
|
"tsup": "^8.5.1",
|
|
57
57
|
"typescript": "^5.7.0",
|
|
58
58
|
"vitest": "^2.1.0",
|
|
59
|
+
"@jarvis/agents": "1.0.0",
|
|
60
|
+
"@jarvis/anthropic": "1.0.0",
|
|
59
61
|
"@jarvis/board": "0.1.0",
|
|
60
62
|
"@jarvis/data": "0.1.0",
|
|
63
|
+
"@jarvis/errors": "1.0.0",
|
|
61
64
|
"@jarvis/logger": "1.0.0",
|
|
62
65
|
"@jarvis/rpc": "1.0.0",
|
|
63
|
-
"@jarvis/errors": "1.0.0",
|
|
64
66
|
"@jarvis/types": "1.0.0",
|
|
65
67
|
"@jarvis/typescript-config": "1.0.0",
|
|
66
68
|
"@jarvis/ui": "0.1.0",
|
|
67
|
-
"@jarvis/vitest-config": "1.0.0"
|
|
68
|
-
"@jarvis/agents": "1.0.0",
|
|
69
|
-
"@jarvis/anthropic": "1.0.0"
|
|
69
|
+
"@jarvis/vitest-config": "1.0.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"dev": "tsx watch src/bin.ts start --foreground",
|