@rubytech/create-maxy-code 0.1.569 → 0.1.570

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.
Files changed (28) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/PLUGIN.md +3 -3
  3. package/payload/platform/plugins/admin/hooks/__tests__/pdf-text-layer-inject.test.sh +177 -0
  4. package/payload/platform/plugins/admin/hooks/pdf-text-layer-inject.sh +137 -0
  5. package/payload/platform/plugins/admin/skills/a4-print-documents/SKILL.md +12 -1
  6. package/payload/platform/plugins/admin/skills/a4-print-documents/pdf-inspect.mjs +113 -0
  7. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
  8. package/payload/platform/plugins/docs/references/admin-session.md +15 -0
  9. package/payload/platform/scripts/__tests__/mailbox-inject-registered.test.sh +15 -39
  10. package/payload/platform/scripts/__tests__/public-prompt-gate-registered.test.sh +22 -37
  11. package/payload/platform/scripts/__tests__/public-surface-registered.test.sh +8 -31
  12. package/payload/platform/scripts/setup-account.sh +7 -62
  13. package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.d.ts +129 -0
  14. package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.d.ts.map +1 -0
  15. package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.js +344 -0
  16. package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.js.map +1 -0
  17. package/payload/platform/services/claude-session-manager/dist/index.js +20 -0
  18. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  19. package/payload/platform/templates/account-settings.json +6 -0
  20. package/payload/server/server.js +750 -656
  21. package/payload/platform/scripts/lib/__tests__/account-settings-askgate.test.sh +0 -144
  22. package/payload/platform/scripts/lib/__tests__/account-settings-mailbox-inject.test.sh +0 -166
  23. package/payload/platform/scripts/lib/__tests__/account-settings-pdf-conformance.test.sh +0 -151
  24. package/payload/platform/scripts/lib/__tests__/account-settings-public-surface.test.sh +0 -109
  25. package/payload/platform/scripts/lib/account-settings-askgate.sh +0 -98
  26. package/payload/platform/scripts/lib/account-settings-mailbox-inject.sh +0 -91
  27. package/payload/platform/scripts/lib/account-settings-pdf-conformance.sh +0 -98
  28. package/payload/platform/scripts/lib/account-settings-public-surface.sh +0 -109
@@ -1,98 +0,0 @@
1
- # account-settings-askgate.sh — retrofit the AskUserQuestion carrier gate onto
2
- # existing accounts' .claude/settings.json. Task 1683.
3
- #
4
- # Task 1552 added askuserquestion-channel-carrier-gate.sh as a second command on
5
- # the AskUserQuestion PreToolUse matcher in provision-account-dir.sh. That writer
6
- # only runs at account-provision time; the upgrade path re-provisions the house
7
- # account but NOT existing client sub-accounts, so any account provisioned before
8
- # 1552 keeps a stale matcher with no carrier gate and re-wedges on a channel
9
- # AskUserQuestion (live SiteDesk incident: session d39a22b0, account 2078cb54,
10
- # 2026-07-15). This lib is the standing backfill: setup-account.sh reconciles
11
- # every account on every install so the gate reaches pre-1552 accounts.
12
- #
13
- # Requires jq. Idempotent. Never echoes file contents. Fail-open (nudge, not
14
- # brick): any unusable file logs a status and is left untouched.
15
- #
16
- # Sourced by setup-account.sh; also runnable standalone for a manual repair.
17
-
18
- # The exact command strings provision-account-dir.sh writes. $PLATFORM_ROOT is a
19
- # literal in the settings file, resolved by Claude Code at hook-run time.
20
- _ASKGATE_CARRIER='bash $PLATFORM_ROOT/plugins/admin/hooks/askuserquestion-channel-carrier-gate.sh'
21
- _ASKGATE_INVESTIGATE='bash $PLATFORM_ROOT/plugins/admin/hooks/askuserquestion-investigate-gate.sh'
22
-
23
- # ensure_askgate_carrier <settings_file>
24
- # Guarantees the AskUserQuestion PreToolUse matcher carries the carrier-gate
25
- # command: appends it if the matcher exists without it, or adds the whole matcher
26
- # (both gates, investigate first) if the matcher is absent. Logs exactly one
27
- # `[backfill-1683] file=<f> status=<absent|no-hooks|already-set|updated|rewrite-failed>`
28
- # to stdout. Always returns 0.
29
- ensure_askgate_carrier() {
30
- local f="$1"
31
- if [ ! -f "$f" ]; then
32
- echo "[backfill-1683] file=$f status=absent"
33
- return 0
34
- fi
35
- # Patchable only when the file is valid JSON with a PreToolUse array.
36
- if ! jq -e '.hooks.PreToolUse | type == "array"' "$f" >/dev/null 2>&1; then
37
- if jq -e . "$f" >/dev/null 2>&1; then
38
- echo "[backfill-1683] file=$f status=no-hooks"
39
- else
40
- echo "[backfill-1683] file=$f status=rewrite-failed"
41
- fi
42
- return 0
43
- fi
44
- local tmp="$f.1683.tmp"
45
- if ! jq \
46
- --arg carrier "$_ASKGATE_CARRIER" \
47
- --arg invest "$_ASKGATE_INVESTIGATE" '
48
- .hooks.PreToolUse |= (
49
- if any(.[]; .matcher == "AskUserQuestion")
50
- then map(
51
- if .matcher == "AskUserQuestion"
52
- then .hooks = (
53
- if any(.hooks[]; .command == $carrier)
54
- then .hooks
55
- else .hooks + [{type: "command", command: $carrier}]
56
- end)
57
- else . end)
58
- else . + [{matcher: "AskUserQuestion", hooks: [{type: "command", command: $invest}, {type: "command", command: $carrier}]}]
59
- end)
60
- ' "$f" > "$tmp" 2>/dev/null; then
61
- rm -f "$tmp"
62
- echo "[backfill-1683] file=$f status=rewrite-failed"
63
- return 0
64
- fi
65
- # Semantic no-op? Compare canonical forms; leave the file byte-identical if so.
66
- # `|| true` keeps a jq failure here (e.g. $f truncated by a concurrent writer
67
- # between the type-check above and this read) from tripping a caller's `set -e`
68
- # and aborting the whole install — this lib is fail-open by contract.
69
- local before after
70
- before="$(jq -S . "$f" 2>/dev/null || true)"
71
- after="$(jq -S . "$tmp" 2>/dev/null || true)"
72
- if [ "$before" = "$after" ]; then
73
- rm -f "$tmp"
74
- echo "[backfill-1683] file=$f status=already-set"
75
- return 0
76
- fi
77
- if mv "$tmp" "$f"; then
78
- echo "[backfill-1683] file=$f status=updated"
79
- else
80
- rm -f "$tmp"
81
- echo "[backfill-1683] file=$f status=rewrite-failed"
82
- fi
83
- return 0
84
- }
85
-
86
- # reconcile_all_accounts_askgate <accounts_dir>
87
- # Standing check + backfill: every account dir with an account.json gets its
88
- # AskUserQuestion matcher's carrier gate ensured. Mirrors
89
- # reconcile_all_accounts_owned_dirs.
90
- reconcile_all_accounts_askgate() {
91
- local accts="$1"
92
- [ -d "$accts" ] || return 0
93
- local acct
94
- for acct in "$accts"/*/; do
95
- [ -f "$acct/account.json" ] || continue
96
- ensure_askgate_carrier "$acct/.claude/settings.json"
97
- done
98
- }
@@ -1,91 +0,0 @@
1
- # account-settings-mailbox-inject.sh — retrofit the per-turn <mailboxes>
2
- # injection hook onto existing accounts' .claude/settings.json. Task 2157.
3
- #
4
- # provision-account-dir.sh writes the UserPromptSubmit array only at provision
5
- # time, and setup-account.sh re-provisions the HOUSE account only: a client
6
- # sub-account's settings.json is written once, at creation, by the admin-core
7
- # account-lifecycle tool, and no install ever rewrites it. Without this lib the
8
- # hook reaches house accounts only, and no device gate would notice, because the
9
- # verification account on a single-account install IS that install's house
10
- # account. Same shape as account-settings-askgate.sh (Task 1683) and
11
- # account-settings-pdf-conformance.sh (Task 1929).
12
- #
13
- # Requires jq. Idempotent. Never echoes file contents. Fail-open (nudge, not
14
- # brick): any unusable file logs a status and is left untouched.
15
- #
16
- # Sourced by setup-account.sh; also runnable standalone for a manual repair.
17
-
18
- # The exact command string provision-account-dir.sh writes. $PLATFORM_ROOT is a
19
- # literal in the settings file, resolved by Claude Code at hook-run time.
20
- _MBXINJECT_CMD='bash $PLATFORM_ROOT/plugins/admin/hooks/mailbox-inject.sh'
21
-
22
- # ensure_mailbox_inject_hook <settings_file>
23
- # Guarantees the UserPromptSubmit array carries the mailbox-inject command:
24
- # appends it to the first entry when the array exists without it, or adds a whole
25
- # entry when the array is empty. Logs exactly one
26
- # `[backfill-2157] file=<f> status=<absent|no-hooks|already-set|updated|rewrite-failed>`
27
- # to stdout. Always returns 0.
28
- ensure_mailbox_inject_hook() {
29
- local f="$1"
30
- if [ ! -f "$f" ]; then
31
- echo "[backfill-2157] file=$f status=absent"
32
- return 0
33
- fi
34
- # Patchable only when the file is valid JSON with a UserPromptSubmit array.
35
- if ! jq -e '.hooks.UserPromptSubmit | type == "array"' "$f" >/dev/null 2>&1; then
36
- if jq -e . "$f" >/dev/null 2>&1; then
37
- echo "[backfill-2157] file=$f status=no-hooks"
38
- else
39
- echo "[backfill-2157] file=$f status=rewrite-failed"
40
- fi
41
- return 0
42
- fi
43
- local tmp="$f.2157.tmp"
44
- if ! jq --arg cmd "$_MBXINJECT_CMD" '
45
- .hooks.UserPromptSubmit |= (
46
- if length == 0
47
- then [{hooks: [{type: "command", command: $cmd}]}]
48
- else
49
- if any(.[]; (.hooks // []) | any(.[]; .command == $cmd))
50
- then .
51
- else (.[0].hooks = ((.[0].hooks // []) + [{type: "command", command: $cmd}]))
52
- end
53
- end)
54
- ' "$f" > "$tmp" 2>/dev/null; then
55
- rm -f "$tmp"
56
- echo "[backfill-2157] file=$f status=rewrite-failed"
57
- return 0
58
- fi
59
- # Semantic no-op? Compare canonical forms; leave the file byte-identical if so.
60
- # `|| true` keeps a jq failure here (e.g. $f truncated by a concurrent writer
61
- # between the type-check above and this read) from tripping a caller's `set -e`
62
- # and aborting the whole install — this lib is fail-open by contract.
63
- local before after
64
- before="$(jq -S . "$f" 2>/dev/null || true)"
65
- after="$(jq -S . "$tmp" 2>/dev/null || true)"
66
- if [ "$before" = "$after" ]; then
67
- rm -f "$tmp"
68
- echo "[backfill-2157] file=$f status=already-set"
69
- return 0
70
- fi
71
- if mv "$tmp" "$f"; then
72
- echo "[backfill-2157] file=$f status=updated"
73
- else
74
- rm -f "$tmp"
75
- echo "[backfill-2157] file=$f status=rewrite-failed"
76
- fi
77
- return 0
78
- }
79
-
80
- # reconcile_all_accounts_mailbox_inject <accounts_dir>
81
- # Standing check + backfill: every account dir with an account.json gets the
82
- # mailbox-inject hook ensured. Mirrors reconcile_all_accounts_askgate.
83
- reconcile_all_accounts_mailbox_inject() {
84
- local accts="$1"
85
- [ -d "$accts" ] || return 0
86
- local acct
87
- for acct in "$accts"/*/; do
88
- [ -f "$acct/account.json" ] || continue
89
- ensure_mailbox_inject_hook "$acct/.claude/settings.json"
90
- done
91
- }
@@ -1,98 +0,0 @@
1
- # account-settings-pdf-conformance.sh — retrofit the quote-render PDF-conformance
2
- # PostToolUse matcher onto existing accounts' .claude/settings.json. Task 1929.
3
- #
4
- # Task 1922 added a PostToolUse matcher on the browser-pdf-save tool running
5
- # quote-render-pdf-conformance.sh to provision-account-dir.sh. That writer only
6
- # runs at account-provision time; the upgrade path re-provisions the house
7
- # account but NOT existing client sub-accounts, so any account provisioned before
8
- # 1922 keeps a settings.json without the matcher and never runs the PDF gate
9
- # (live glsmith is such an account). This lib is the standing backfill:
10
- # setup-account.sh reconciles every account on every install so the gate reaches
11
- # pre-1922 accounts. Mirrors account-settings-askgate.sh (Task 1683).
12
- #
13
- # Requires jq. Idempotent. Never echoes file contents. Fail-open (nudge, not
14
- # brick): any unusable file logs a status and is left untouched.
15
- #
16
- # Sourced by setup-account.sh; also runnable standalone for a manual repair.
17
-
18
- # The exact command string provision-account-dir.sh writes. $PLATFORM_ROOT is a
19
- # literal in the settings file, resolved by Claude Code at hook-run time.
20
- _PDF_CONFORMANCE_MATCHER='mcp__plugin_browser_browser__browser-pdf-save'
21
- _PDF_CONFORMANCE_CMD='bash $PLATFORM_ROOT/plugins/admin/hooks/quote-render-pdf-conformance.sh'
22
-
23
- # ensure_pdf_conformance_matcher <settings_file>
24
- # Guarantees the PostToolUse browser-pdf-save matcher carries the conformance
25
- # command: appends it if the matcher exists without it, or adds the whole matcher
26
- # (single conformance command) if the matcher is absent. Logs exactly one
27
- # `[backfill-1929] file=<f> status=<absent|no-hooks|already-set|updated|rewrite-failed>`
28
- # to stdout. Always returns 0.
29
- ensure_pdf_conformance_matcher() {
30
- local f="$1"
31
- if [ ! -f "$f" ]; then
32
- echo "[backfill-1929] file=$f status=absent"
33
- return 0
34
- fi
35
- # Patchable only when the file is valid JSON with a PostToolUse array.
36
- if ! jq -e '.hooks.PostToolUse | type == "array"' "$f" >/dev/null 2>&1; then
37
- if jq -e . "$f" >/dev/null 2>&1; then
38
- echo "[backfill-1929] file=$f status=no-hooks"
39
- else
40
- echo "[backfill-1929] file=$f status=rewrite-failed"
41
- fi
42
- return 0
43
- fi
44
- local tmp="$f.1929.tmp"
45
- if ! jq \
46
- --arg matcher "$_PDF_CONFORMANCE_MATCHER" \
47
- --arg cmd "$_PDF_CONFORMANCE_CMD" '
48
- .hooks.PostToolUse |= (
49
- if any(.[]; .matcher == $matcher)
50
- then map(
51
- if .matcher == $matcher
52
- then .hooks = (
53
- if any(.hooks[]; .command == $cmd)
54
- then .hooks
55
- else .hooks + [{type: "command", command: $cmd}]
56
- end)
57
- else . end)
58
- else . + [{matcher: $matcher, hooks: [{type: "command", command: $cmd}]}]
59
- end)
60
- ' "$f" > "$tmp" 2>/dev/null; then
61
- rm -f "$tmp"
62
- echo "[backfill-1929] file=$f status=rewrite-failed"
63
- return 0
64
- fi
65
- # Semantic no-op? Compare canonical forms; leave the file byte-identical if so.
66
- # `|| true` keeps a jq failure here (e.g. $f truncated by a concurrent writer
67
- # between the type-check above and this read) from tripping a caller's `set -e`
68
- # and aborting the whole install. This lib is fail-open by contract.
69
- local before after
70
- before="$(jq -S . "$f" 2>/dev/null || true)"
71
- after="$(jq -S . "$tmp" 2>/dev/null || true)"
72
- if [ "$before" = "$after" ]; then
73
- rm -f "$tmp"
74
- echo "[backfill-1929] file=$f status=already-set"
75
- return 0
76
- fi
77
- if mv "$tmp" "$f"; then
78
- echo "[backfill-1929] file=$f status=updated"
79
- else
80
- rm -f "$tmp"
81
- echo "[backfill-1929] file=$f status=rewrite-failed"
82
- fi
83
- return 0
84
- }
85
-
86
- # reconcile_all_accounts_pdf_conformance <accounts_dir>
87
- # Standing check + backfill: every account dir with an account.json gets its
88
- # PostToolUse browser-pdf-save matcher's conformance command ensured. Mirrors
89
- # reconcile_all_accounts_askgate.
90
- reconcile_all_accounts_pdf_conformance() {
91
- local accts="$1"
92
- [ -d "$accts" ] || return 0
93
- local acct
94
- for acct in "$accts"/*/; do
95
- [ -f "$acct/account.json" ] || continue
96
- ensure_pdf_conformance_matcher "$acct/.claude/settings.json"
97
- done
98
- }
@@ -1,109 +0,0 @@
1
- # account-settings-public-surface.sh — retrofit the realised-public-tool-surface
2
- # hook onto existing accounts' .claude/settings.json. Task 2339.
3
- #
4
- # provision-account-dir.sh writes the hooks block only at provision time, and
5
- # setup-account.sh re-provisions the HOUSE account only: a client sub-account's
6
- # settings.json is written once, at creation, by the admin-core account-lifecycle
7
- # tool, and no install ever rewrites it. Without this lib the hook reaches house
8
- # accounts only, and the account the 2026-08-01 breach was observed on would keep
9
- # a settings file with no such command — so the instrumentation could not be
10
- # verified where the defect was seen. Same shape as
11
- # account-settings-mailbox-inject.sh (Task 2157).
12
- #
13
- # Requires jq. Idempotent. Never echoes file contents. Fail-open (nudge, not
14
- # brick): any unusable file logs a status and is left untouched.
15
- #
16
- # Sourced by setup-account.sh; also runnable standalone for a manual repair.
17
-
18
- # The exact command string provision-account-dir.sh writes. $PLATFORM_ROOT is a
19
- # literal in the settings file, resolved by Claude Code at hook-run time.
20
- _PUBSURFACE_CMD='bash $PLATFORM_ROOT/plugins/admin/hooks/public-tool-surface.sh'
21
-
22
- # ensure_public_surface_hook <settings_file>
23
- # Guarantees the matcher-less PreToolUse entry, the UserPromptSubmit entry and
24
- # the Stop entry all carry the command. The PreToolUse target is the
25
- # matcher-less entry specifically: a matcher-scoped entry would narrow the hook
26
- # to one tool, and the whole point is every tool. UserPromptSubmit is the
27
- # turn-start reset without which a killed turn's tally inflates the next turn's
28
- # census. Logs exactly one
29
- # `[backfill-2339] file=<f> status=<absent|no-hooks|already-set|updated|rewrite-failed>`
30
- # to stdout. Always returns 0.
31
- ensure_public_surface_hook() {
32
- local f="$1"
33
- if [ ! -f "$f" ]; then
34
- echo "[backfill-2339] file=$f status=absent"
35
- return 0
36
- fi
37
- # Patchable only when the file is valid JSON with both arrays.
38
- if ! jq -e '(.hooks.PreToolUse | type == "array") and (.hooks.UserPromptSubmit | type == "array") and (.hooks.Stop | type == "array")' "$f" >/dev/null 2>&1; then
39
- if jq -e . "$f" >/dev/null 2>&1; then
40
- echo "[backfill-2339] file=$f status=no-hooks"
41
- else
42
- echo "[backfill-2339] file=$f status=rewrite-failed"
43
- fi
44
- return 0
45
- fi
46
- local tmp="$f.2339.tmp"
47
- if ! jq --arg cmd "$_PUBSURFACE_CMD" '
48
- .hooks.PreToolUse |= (
49
- if any(.[]; (.hooks // []) | any(.[]; .command == $cmd))
50
- then .
51
- elif any(.[]; has("matcher") | not)
52
- then map(if (has("matcher") | not)
53
- then .hooks = ((.hooks // []) + [{type: "command", command: $cmd}])
54
- else . end)
55
- else . + [{hooks: [{type: "command", command: $cmd}]}]
56
- end)
57
- | .hooks.UserPromptSubmit |= (
58
- if any(.[]; (.hooks // []) | any(.[]; .command == $cmd))
59
- then .
60
- elif length == 0
61
- then [{hooks: [{type: "command", command: $cmd}]}]
62
- else (.[0].hooks = ((.[0].hooks // []) + [{type: "command", command: $cmd}]))
63
- end)
64
- | .hooks.Stop |= (
65
- if any(.[]; (.hooks // []) | any(.[]; .command == $cmd))
66
- then .
67
- elif length == 0
68
- then [{hooks: [{type: "command", command: $cmd}]}]
69
- else (.[0].hooks = ((.[0].hooks // []) + [{type: "command", command: $cmd}]))
70
- end)
71
- ' "$f" > "$tmp" 2>/dev/null; then
72
- rm -f "$tmp"
73
- echo "[backfill-2339] file=$f status=rewrite-failed"
74
- return 0
75
- fi
76
- # Semantic no-op? Compare canonical forms; leave the file byte-identical if so.
77
- # `|| true` keeps a jq failure here (e.g. $f truncated by a concurrent writer
78
- # between the type-check above and this read) from tripping a caller's `set -e`
79
- # and aborting the whole install — this lib is fail-open by contract.
80
- local before after
81
- before="$(jq -S . "$f" 2>/dev/null || true)"
82
- after="$(jq -S . "$tmp" 2>/dev/null || true)"
83
- if [ "$before" = "$after" ]; then
84
- rm -f "$tmp"
85
- echo "[backfill-2339] file=$f status=already-set"
86
- return 0
87
- fi
88
- if mv "$tmp" "$f"; then
89
- echo "[backfill-2339] file=$f status=updated"
90
- else
91
- rm -f "$tmp"
92
- echo "[backfill-2339] file=$f status=rewrite-failed"
93
- fi
94
- return 0
95
- }
96
-
97
- # reconcile_all_accounts_public_surface <accounts_dir>
98
- # Standing check + backfill: every account dir with an account.json gets the
99
- # realised-surface hook ensured on both events. Mirrors
100
- # reconcile_all_accounts_mailbox_inject.
101
- reconcile_all_accounts_public_surface() {
102
- local accts="$1"
103
- [ -d "$accts" ] || return 0
104
- local acct
105
- for acct in "$accts"/*/; do
106
- [ -f "$acct/account.json" ] || continue
107
- ensure_public_surface_hook "$acct/.claude/settings.json"
108
- done
109
- }