Última actividad 3 weeks ago

Revisión 840f87f271963bb0d7bec83b974d5f32d8cecb8b

ELI5.mdx Sin formato
1---
2name: ELI5
3description: keep it simple pls
4keep-coding-instructions: true
5---
6
7It's been a long day and my brain is fried, talk to me like I'm 5.
8
9Small words, short sentences, short paragraphs. If you have to use
10a big word, explain it right after. Only return what's actually necessary.
11
12Just tell me what you did, did it work, what do I do now.
13
14If I have to decide something: 2 options max, the context I need to pick fast,
15and which one you'd go with.
16
17Keep paths and commands exact. I have no brain cells left for the rest.
README.md Sin formato

AI Coding Agent Skill Collection

Quick Install: Grilling Question Tools

Install or update the question-tool preference for Claude Code, Codex, and OpenCode in one command:

bash -o pipefail -c 'curl -fsSL https://opengist.resetrix.work/weehong/9e381dc89dff4670b7232b910454f056/raw/HEAD/install-question-tools.sh | bash'

Trust check: this runs remote code and downloads remote instructions from this gist. Read both before running if you do not already trust the publisher and server. pipefail reports download failures; it is not a security sandbox or a guarantee against executing partially downloaded shell code.

Quick links: installer | authoritative policy | ELI5 writing style

Download and Inspect Instead

Run in a scratch directory. These downloads alone do not install anything:

base=https://opengist.resetrix.work/weehong/9e381dc89dff4670b7232b910454f056
curl -fsSL "$base/raw/HEAD/install-question-tools.sh" -o install-question-tools.sh
curl -fsSL "$base/raw/HEAD/grilling-question-tools.md" -o grilling-question-tools.md
less install-question-tools.sh grilling-question-tools.md
# After inspection:
bash install-question-tools.sh

By default the installer fetches the policy at HEAD, not the inspected local copy. To avoid changes between inspection and installation, get a full commit hash from the gist's Revisions, replace HEAD in both download URLs with that hash, and run QUESTION_TOOLS_REVISION=<same-full-40-character-hash> bash install-question-tools.sh. The revision variable controls the policy download, not the installer download.

Requirements and Scope

  • Linux, macOS, or WSL; Bash 3.2+, Python 3.8+, and curl with HTTPS support.
  • Run as your normal user, without sudo, and with no concurrent installer or editor changing the destination files. Native Windows shells are not supported.
  • This installs instructions only, not the Matt Pocock skills, tools, plugins, or permissions. Install your desired grilling skills separately.
  • Only Matt Pocock grilling flows use this preference. The policy retains the flow's pacing and recommendations, custom answers, unresolved decisions, and text fallback when the native question tool is unavailable or restricted.
  • This is not runtime enforcement. Host permissions, mode restrictions, instruction precedence, and agent instruction-loading limits still apply.

Destinations

All three destinations are installed, even if a corresponding CLI is not yet installed. Export overrides before running the quick command so both shells inherit them. Empty variables use defaults; paths must be absolute, without .. components. Spaces are supported.

Agent Default file Override
Claude Code ~/.claude/CLAUDE.md $CLAUDE_CONFIG_DIR/CLAUDE.md
Codex ~/.codex/AGENTS.md $CODEX_HOME/AGENTS.md
OpenCode ~/.config/opencode/AGENTS.md $OPENCODE_CONFIG_DIR/AGENTS.md, otherwise $XDG_CONFIG_HOME/opencode/AGENTS.md

HOME supplies ~. Current OpenCode supports OPENCODE_CONFIG_DIR for global instructions; older versions may only read the XDG location. For an older release, leave OPENCODE_CONFIG_DIR unset and use XDG_CONFIG_HOME instead. See OpenCode instruction loading and global paths. OpenCode normally prefers its own global AGENTS.md over the Claude fallback: creating this file can stop fallback loading of ~/.claude/CLAUDE.md. If you rely on unrelated instructions in that fallback, explicitly configure them in OpenCode's instructions setting before installing. Codex's AGENTS.override.md, if present, can take precedence over AGENTS.md; review it if the new preference is not being loaded.

Updates and Safety

Rerun the quick command to fetch the latest policy and replace its managed block. Identical reruns leave file bytes unchanged and create no new backups. The authoritative policy is grilling-question-tools.md; the installer embeds its downloaded content rather than maintaining another policy copy.

  • Download errors or an invalid/incomplete policy abort before destination edits. Validation checks UTF-8, versioned start/end markers, title, and all seven numbered rules. These are integrity sanity checks, not a signature.
  • Every destination is preflighted before any directories, backups, or files are created. Malformed or duplicate managed markers abort the entire run.
  • The unique HTML markers are <!-- BEGIN MATT-POCOCK-GRILLING-QUESTION-TOOLS --> and <!-- END MATT-POCOCK-GRILLING-QUESTION-TOOLS -->. Keep them intact.
  • Bytes outside an existing managed block are preserved exactly. A first installation appends a separator and block without changing existing bytes.
  • Each changed existing file gets a byte-for-byte sibling backup named <filename>.question-tools-backup-<unique-suffix> (private mode 0600). New files need no backup. Paths are printed; previous backups are never replaced.
  • Symlinked files and ancestor directories are refused without following them. Use physical directory paths and regular files, or integrate the policy manually through your dotfile manager. The installer never unlinks symlinks.
  • Replacements are atomic per file, not a transaction across all three files. Staging and backups precede replacements, but disk/permission errors during writing can leave directories/backups or a partial install. Inspect the printed paths, restore from backups if needed, and rerun after fixing the cause. File modes are retained; ownership, ACLs, extended attributes and hard-link relationships are not preserved by replacement. Avoid concurrent writers.

After installation, start fresh Claude Code and Codex sessions, and quit and restart OpenCode. Ask the agent which instruction files it loaded if the preference is missing. To uninstall, remove only the managed block from each destination, or restore a backup if it will not erase newer unrelated edits.

Existing Style

ELI5.mdx is the original short, plain-language writing style. It is preserved unchanged and is not installed by this script.

grilling-question-tools.md Sin formato

Question Tools for Matt Pocock Grilling Flows

Scope: apply only while running Matt Pocock's grilling flows (grill-me, grilling, grill-with-docs, loop-me, or a skill explicitly delegating its interview to one of these). This changes question delivery, not the flow's research, decision criteria, documentation, or completion requirements. Ordinary coding conversations and unrelated skills keep their own behavior.

  1. Research what the codebase can answer before asking the user. The main conversation agent owns the interview; subagents return findings and proposed questions to it rather than independently prompting the user.
  2. Use the host's native interactive question tool when exposed and permitted in the current session: Claude Code AskUserQuestion, Codex request_user_input, or OpenCode question. Follow its actual schema and mode/permission restrictions. Do not invent a tool, change modes merely to unlock one, or bypass a restriction. In Codex, request_user_input may be limited to Plan mode; use the fallback when it is unavailable.
  3. Preserve the originating flow's round size and pacing. If it calls for one question at a time, ask one. If it allows a round of independent questions, batch only those that can be answered without knowing another answer. Wait for each answer before formulating dependent follow-ups. Split rounds across sequential tool calls when question, option, or text limits require it; retain every decision rather than silently dropping questions.
  4. Give enough context to decide, concrete options with tradeoffs, and your recommendation with a short reason when you have one. Mark the recommended option clearly. Keep choices neutral enough to disagree with; never invent a recommendation just to fill the UI. Put context outside the tool if its field limits would lose necessary detail.
  5. Preserve custom responses: use the tool's built-in free-text/Other facility where available. If it cannot accept a needed custom answer, invite a plain text reply instead. Do not force an open-ended question into false choices or interpret Other as agreement with a listed option.
  6. Treat skipped, dismissed, empty, or ambiguous answers as unresolved, not consent and not acceptance of the recommendation. Clarify a blocking gap or explicitly defer it with the user's agreement. Track unresolved decisions and keep them out of the confirmed decisions in any spec, ADR, or summary.
  7. If the native tool is absent, disallowed, fails, or cannot express the question faithfully, ask in plain text and wait. Use the same round rules, numbered questions/options, recommendation and reason, and an explicit invitation to give a custom answer. Resume the native tool when usable.

This is an instruction preference, not runtime enforcement. Higher-priority instructions and host restrictions still apply. Finish only when the original flow's completion criteria are met; changing the UI does not satisfy them.

install-question-tools.sh Sin formato
1#!/usr/bin/env bash
2# Requires Bash 3.2+, Python 3.8+, and curl. No sudo; run one installer at a time.
3set -euo pipefail
4
5# Defining the complete function before calling it also avoids starting an
6# installation from a download truncated inside the embedded Python program.
7main() {
8 command -v python3 >/dev/null || { printf '%s\n' 'Python 3.8+ is required.' >&2; return 1; }
9 command -v curl >/dev/null || { printf '%s\n' 'curl is required.' >&2; return 1; }
10 python3 - <<'PY'
11import os
12import re
13import stat
14import subprocess
15import sys
16import tempfile
17from pathlib import Path
18
19BEGIN = b'<!-- BEGIN MATT-POCOCK-GRILLING-QUESTION-TOOLS -->'
20END = b'<!-- END MATT-POCOCK-GRILLING-QUESTION-TOOLS -->'
21TOKEN = b'MATT-POCOCK-GRILLING-QUESTION-TOOLS'
22POLICY_BEGIN = '<!-- BEGIN MATT-POCOCK-GRILLING-QUESTION-POLICY v1 -->'
23POLICY_END = '<!-- END MATT-POCOCK-GRILLING-QUESTION-POLICY v1 -->'
24BASE = 'https://opengist.resetrix.work/weehong/9e381dc89dff4670b7232b910454f056'
25
26
27def check_path(path):
28 for part in [path] + list(path.parents):
29 if part.is_symlink():
30 raise ValueError('Symlink refused: %s. Use physical directories and a regular instruction file; manage linked files manually.' % part)
31 if part.exists() and not (part.is_file() if part == path else part.is_dir()):
32 raise ValueError('Not a regular file/directory: %s' % part)
33 parent = path.parent
34 while not parent.exists():
35 parent = parent.parent
36 if not os.access(parent, os.W_OK | os.X_OK):
37 raise ValueError('Directory is not writable/searchable: %s' % parent)
38 if path.exists() and not os.access(path, os.R_OK | os.W_OK):
39 raise ValueError('Instruction file is not readable/writable: %s' % path)
40
41
42def install():
43 if sys.version_info < (3, 8):
44 raise ValueError('Python 3.8+ is required.')
45 revision = os.environ.get('QUESTION_TOOLS_REVISION') or 'HEAD'
46 if revision != 'HEAD' and not re.fullmatch(r'[0-9a-fA-F]{40}', revision):
47 raise ValueError('QUESTION_TOOLS_REVISION must be HEAD or a full 40-character commit hash.')
48 url = BASE + '/raw/' + revision + '/grilling-question-tools.md'
49 result = subprocess.run(['curl', '-fsSL', '--proto', '=https', '--proto-redir', '=https',
50 '--connect-timeout', '15', '--max-time', '60', url],
51 stdout=subprocess.PIPE, check=True)
52 policy = result.stdout.decode('utf-8')
53 lines = policy.splitlines()
54 if (not lines or lines[0] != POLICY_BEGIN or lines[-1] != POLICY_END
55 or policy.count(POLICY_BEGIN) != 1 or policy.count(POLICY_END) != 1
56 or len(policy) > 32768 or '\x00' in policy
57 or TOKEN.decode() in policy
58 or not policy.startswith(POLICY_BEGIN + '\n# Question Tools for Matt Pocock Grilling Flows\n')
59 or not all('\n%d. ' % i in policy for i in range(1, 8))):
60 raise ValueError('Downloaded policy is incomplete or invalid; no instruction files changed.')
61 block = BEGIN + b'\n' + policy.rstrip('\r\n').encode('utf-8') + b'\n' + END
62 home = os.environ.get('HOME')
63 if not home or not os.path.isabs(home):
64 raise ValueError('HOME must be an absolute path.')
65 directories = [
66 os.environ.get('CLAUDE_CONFIG_DIR') or home + '/.claude',
67 os.environ.get('CODEX_HOME') or home + '/.codex',
68 os.environ.get('OPENCODE_CONFIG_DIR') or
69 (os.environ.get('XDG_CONFIG_HOME') or home + '/.config') + '/opencode',
70 ]
71 if any(not os.path.isabs(d) or '..' in Path(d).parts for d in directories):
72 raise ValueError('Config directories must be absolute paths without .. components.')
73 paths = list(dict.fromkeys(Path(d) / name for d, name in
74 zip(directories, ['CLAUDE.md', 'AGENTS.md', 'AGENTS.md'])))
75 changes = []
76 # Preflight every destination before creating directories, backups, or files.
77 for path in paths:
78 check_path(path)
79 exists = path.exists()
80 old = path.read_bytes() if exists else b''
81 if TOKEN in old:
82 if old.count(TOKEN) != 2 or old.count(BEGIN) != 1 or old.count(END) != 1:
83 raise ValueError('Malformed/duplicate managed markers: %s. Repair them manually before rerunning.' % path)
84 start, end = old.index(BEGIN), old.index(END)
85 after = end + len(END)
86 if (end < start or (start and old[start-1:start] != b'\n')
87 or old[end-1:end] != b'\n'
88 or (old[after:] and not old[after:].startswith((b'\n', b'\r\n')))
89 or not old[start+len(BEGIN):].startswith((b'\n', b'\r\n'))):
90 raise ValueError('Malformed managed marker boundaries: %s' % path)
91 new = old[:start] + block + old[after:]
92 else:
93 separator = (b'\n' if old.endswith(b'\n') else b'\n\n') if old else b''
94 new = old + separator + block + b'\n'
95 if new != old:
96 changes.append((path, exists, old, new))
97 else:
98 print('Unchanged: %s' % path)
99
100 staged = []
101 try:
102 for path, exists, old, new in changes:
103 check_path(path)
104 if path.exists() != exists or (exists and path.read_bytes() != old):
105 raise ValueError('File changed during installation: %s. Retry with other writers stopped.' % path)
106 path.parent.mkdir(parents=True, exist_ok=True)
107 mode = stat.S_IMODE(path.stat().st_mode) if exists else 0o600
108 fd, temporary = tempfile.mkstemp(prefix='.' + path.name + '.question-tools-', dir=str(path.parent))
109 staged.append((path, temporary))
110 with os.fdopen(fd, 'wb') as stream:
111 stream.write(new)
112 stream.flush()
113 os.fsync(stream.fileno())
114 os.fchmod(stream.fileno(), mode)
115 if exists:
116 fd, backup = tempfile.mkstemp(prefix=path.name + '.question-tools-backup-', dir=str(path.parent))
117 with os.fdopen(fd, 'wb') as stream:
118 stream.write(old)
119 stream.flush()
120 os.fsync(stream.fileno())
121 print('Backup: %s' % backup)
122 for path, temporary in staged:
123 os.replace(temporary, path)
124 print('Updated: %s' % path)
125 finally:
126 for _, temporary in staged:
127 if os.path.exists(temporary):
128 os.unlink(temporary)
129 print('Policy source: %s' % url)
130 print('Start fresh Claude Code/Codex sessions; quit and restart OpenCode.')
131
132
133try:
134 install()
135except (OSError, ValueError, subprocess.SubprocessError) as error:
136 print('Installation failed: %s' % error, file=sys.stderr)
137 sys.exit(1)
138PY
139}
140
141main "$@"
142