Conversation
Synced from ~/.cursor/ with CLAUDE.md generation and skills symlink for Claude Code compatibility. Includes setup.sh for deploying to new machines.
Document the current repo structure, workflow skills, and shared scripts using the older conventions README format as a template.
task-review: resolve target repo by grepping code for concrete symbols, not task text. Title/description demoted to hints; prefix table kept as an exception shortcut; linked PRs short-circuit; cross-repo work splits into Asana subtasks. pr-create: drop all reviewer-assignment logic. Reviewer choice is a human step; status-setting and review-hour estimation went with it. --asana-attach remains. one-shot: stop defaulting --asana-assign. --asana-attach only. pr-land: add CHANGELOG placement warning handling so dated-release entries can be moved to Unreleased/staging before pushing.
- New slot-fixup.sh: slot HEAD fixup next to its target's group (used by pr-address and bugbot after each lint-commit.sh). - pr-finalize-fixups.sh: derive mode (autosquash | preserve) from the latest human activity on the PR; new squash-stale subcommand for the Fixups-A-before-B trigger; finalize action now push-only in preserve mode, autosquash+force-push in autosquash mode. - pr-address review-mode subcommand: returns mode + latestHumanActivity for shared use. - Simplified human-reviewer detection across pr-address and pr-land scripts: exclude only currentUser + bots (drop prAuthor exclusion). Works uniformly for solo and collab PRs — author gets no special treatment. - pr-address and bugbot SKILL.md: new Step 1.5 (squash-stale before address-pass) and per-fixup slot-fixup.sh after every lint-commit.sh.
- Pull-before-push gate: auto-fetch origin every run; abort --stage/--commit if origin is ahead. - Per-file divergence warnings: compare each affected path's most-recent commit timestamp to the local file's mtime; flag stale-local, deletion, and re-adding-deleted cases. - New JSON output fields: originBranch, originAhead, warnings. - SKILL.md: present new warnings in the dry-run summary; document the new policy and edge cases.
…nch-scan for legacy
| Checkout the PR branch to ensure file reads reflect the PR's code, not the current local branch: | ||
|
|
||
| ```bash | ||
| git fetch origin <headRef> && git checkout <headRef> |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
<headRef> is inserted unquoted into a shell command (git fetch ... && git checkout ...) even though PR branch names are attacker-controlled input.
Impact: A crafted branch name containing shell metacharacters (for example command substitution) can execute arbitrary commands in the review agent environment.
| Resolve the full 40-char SHA for the PR's head branch: | ||
|
|
||
| ```bash | ||
| HEAD_SHA=$(git rev-parse origin/<BRANCH>) |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
<BRANCH> is interpolated directly into git rev-parse origin/<BRANCH> in a shell command path that derives branch names from PR metadata.
Impact: Malicious branch names can trigger command injection during bugbot workflow execution, leading to arbitrary code execution in automation context.
| IMPLEMENTOR_NAME="current user" | ||
|
|
||
| # Phase 3: Create the task | ||
| NOTES_JSON=$(python3 -c "import json; print(json.dumps('''$TASK_NOTES'''))") |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
User/task-controlled content is embedded directly into inline Python source via triple-quoted interpolation ('''$TASK_NOTES''' / '''$TASK_NAME''') in python3 -c calls.
Impact: An input containing ''' can break out of the string literal and inject executable Python statements, resulting in code execution in the automation runtime.
| ext = os.path.splitext(name)[1].lower() | ||
| if ext in DOWNLOAD_EXTS and url: | ||
| os.makedirs(download_dir, exist_ok=True) | ||
| dest = os.path.join(download_dir, name) |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
Attachment filename name is treated as a trusted path segment via os.path.join(download_dir, name) before writing downloaded content.
Impact: Filenames containing traversal segments (for example ../) can write files outside the intended task download directory, enabling workspace boundary bypass and arbitrary file overwrite in reachable paths.
|
|
||
| <rules> | ||
| <rule id="every-turn">Execute at the end of every chat turn without exception.</rule> | ||
| <rule id="full-response">Send the complete response content, not an abbreviated summary.</rule> |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
[Privacy Guard] This rule mandates forwarding the complete chat response every turn to an external Telegram sink without user confirmation or selective minimization.
Impact: Sensitive content (credentials, proprietary code, internal data) can be exfiltrated outside the expected trust boundary by policy.
| jq --arg k "$KEY" --arg v "$VALUE" '.[$k] = $v' env.json > env.json.tmp | ||
| mv env.json.tmp env.json | ||
|
|
||
| git add env.json |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
[Privacy Guard] The script stages and commits env.json updates after accepting raw secret values as direct inputs.
Impact: Secret material can become durable plaintext in git history and propagate through clones/backups, creating long-lived credential exposure risk.
| if (!existsSync(path.join(repoDir, ".git"))) { | ||
| console.error(`Cloning ${repo}...`); | ||
| try { | ||
| execSync(`git clone git@github.com:EdgeApp/${repo}.git "${repoDir}"`, { |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
repo is interpolated into a shell command string passed to execSync (git clone git@github.com:EdgeApp/${repo}.git ...) without validation or argument separation.
Impact: A crafted repo value can trigger shell command injection and arbitrary code execution in the automation environment.
|
|
||
| function fetchPrBody(repo, prNumber) { | ||
| const endpoint = `repos/EdgeApp/${repo}/pulls/${prNumber}`; | ||
| const result = execSync(`gh api "${endpoint}" --jq '.body'`, { |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
fetchPrBody() builds a shell command string with untrusted repo (gh api "repos/EdgeApp/${repo}/pulls/${prNumber}" ...) and executes it via execSync.
Impact: Malicious input can exploit shell expansion and execute arbitrary commands while extracting PR metadata.
| COMMIT_MSG="Update $KEY in env.json" | ||
| fi | ||
|
|
||
| ssh "$SERVER" bash -s -- "$KEY" "$VALUE" "$COMMIT_MSG" "$REMOTE_REPO" <<'REMOTE' |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: MEDIUM
The secret value is passed as a positional CLI argument ("$VALUE") into ssh ... bash -s -- ..., which exposes it in process arguments and often shell history.
Impact: Sensitive credentials can be disclosed to local observers or process-monitoring tooling on the calling host.
Re-validate eslint after update-eslint-warnings runs; if the staged config fails lint (e.g. a naive graduation of a still-dirty file), restore eslint.config.mjs and abort. With this safety net in place, /pr-land's --skip-lint patch (e21dca8) is no longer needed — revert verify-repo.sh, pr-land-{prepare,merge}.sh, edge-repo.js, SKILL.md back to file-scoped lint. Also fixes pr-land-discover.sh's reviewer-state computation: only APPROVED/CHANGES_REQUESTED/DISMISSED change effective state, so a later COMMENTED reply doesn't shadow a prior APPROVED.
|
|
||
| function checkNpmPublished(packageName, version) { | ||
| try { | ||
| const info = execSync(`npm view ${packageName}@${version} version`, { |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
checkNpmPublished builds an execSync shell string using packageName and version from package.json (npm view ${packageName}@${version} version) without argument-safe execution.
Impact: A crafted package name/version can trigger command injection and arbitrary code execution in automation environments running this publish flow.
| const fileCount = changedFiles.split("\n").length; | ||
| console.log(`▶ eslint (${fileCount} changed file${fileCount === 1 ? "" : "s"} vs ${baseRef})...`); | ||
| const eslintResult = runCommandWithLog( | ||
| `npx eslint ${fileList}`, |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
verify-repo.sh builds an eslint command string from git-derived filenames and executes it via execSync; wrapping paths in quotes is not sufficient shell escaping.
Impact: A malicious filename in a branch can break command quoting and execute arbitrary shell commands during repository verification.
| "skills", | ||
| "verify-repo.sh" | ||
| ); | ||
| const baseArg = baseRef != null ? ` --base "${baseRef}"` : ""; |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
runVerification/related helpers interpolate derived repo/path values into execSync shell strings instead of passing argument arrays.
Impact: If attacker-influenced repo/path metadata reaches these call sites, command injection can occur during pr-land preparation/verification operations.
| </sub-step> | ||
| </step> | ||
|
|
||
| <step id="4" name="Upload to gist and clean up"> |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
The standup workflow templates externally sourced task/PR text directly into markdown and then requires uploading the rendered output to a persistent GitHub gist, without a mandatory scrub/redaction step.
Impact: Sensitive code-adjacent content (paths, snippets, internal details) from source systems can be durably exfiltrated to an external artifact.
| </sub-step> | ||
| </step> | ||
|
|
||
| <step id="4" name="Upload to gist and clean up"> |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
The HUDL flow maps GitHub-derived PR text fields into a generated markdown report and uploads it to a gist, but does not require sanitization/minimization of potentially sensitive content.
Impact: Code-related or sensitive operational details can leak into externally stored summaries.
| # Copy file only if changed, respecting --dry-run | ||
| sync_file() { | ||
| local src="$1" dest="$2" | ||
| if [[ ! -f "$dest" ]]; then |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
sync_file copies directly to destination paths without rejecting symlink destinations or enforcing canonical containment.
Impact: A pre-positioned symlink under the sync tree can redirect writes to unintended files, enabling arbitrary file overwrite as the current user.
| for oc_skill_dir in "$OPENCODE_DIR"/skills/*/; do | ||
| [[ -d "$oc_skill_dir" ]] || continue | ||
| local name | ||
| name=$(basename "$oc_skill_dir") |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
Cleanup uses rm -rf on globbed skill directories without symlink validation.
Impact: A symlinked directory entry can cause deletion outside the intended sync root, leading to destructive data loss in attacker-chosen paths.
…es), no-slop, asana ↔ GitHub graceful degrade, yarn→npm migration support - skills/build-and-test: real iOS UI test path via maestro for edge-react-gui - skills/debugger: attach to Hermes JS VM via CDP; set file:line breakpoints - skills/no-slop: writing-style rule + bad/good examples - skills/one-shot: yolo-stop-at-pr, pr-watch-loop, agent_status-on-pending-task - skills/asana-task-update: --attach-pr graceful when ASANA_GITHUB_SECRET unset - skills/install-deps.sh, verify-repo.sh: npm vs yarn auto-detect - scripts/tool-sync.sh: strip trailing slash from glob (double-slash fix)
…ts, slots) Host-local snapshot mirrored for paper trail. The live copy under ~/.config/agent-watcher/ is what runs; this directory is not deployed from. Run up to MAX_CONCURRENT (default 2) agent sessions in parallel, each in its own git worktree, on its own cloned iOS sim, on its own Metro port, behind a load/RAM resource guardrail. Slot accounting is by live tmux sessions, not Asana state, so a dead-but-in-flight task frees its lane. Changed for this work: - asana-watcher.js: multi-pick per tick (cap by live sessions, guardrail, pick oldest N Pending, per-task setup -> clone -> allocate -> spawn). --simulate-* dry-run flags. - rc-watchdog.js: completion sweep reaps the slot (delete sim, remove worktree+branch, release slot) via shared helpers. - spawn-test-session.sh: slot mode (--slot-index ...) exports $AGENT_SIM_UDID / $AGENT_METRO_PORT and cwd=worktree; legacy positional mode preserved. - resume-agent.sh: --recover re-provisions a missing slot for an in-flight task. - asana-config.json: new .watcher.* knobs. - NEW lib/slots.js: atomic, lock-guarded slot allocator (lib + CLI). - NEW clone-ios-sim.sh / delete-ios-sim.sh: per-slot sim clone / delete. - NEW setup-task-workspace.sh / cleanup-task-workspace.sh: per-task worktree. - NEW gc-worktrees.sh: manual orphan cleanup. - NEW slots.json: slot state (initial empty template). - NEW README.md: design doc (architecture, knobs, env contract, limitations). All 5 smoke checks pass (cap, guardrail, worktree setup/cleanup, sim clone/boot/delete, atomic concurrent slot writes). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ept-udid, per-task worktree note)
| maxBuffer: 10 * 1024 * 1024, | ||
| }) | ||
| } catch (err) { | ||
| throw new Error(`curl failed for ${method} ${endpoint}: ${err.message}`) |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: MEDIUM
err.message from execSync is rethrown verbatim here. In Node, that message includes the failed command string, which in this call contains Authorization: Bearer ${TOKEN}.
Impact: if this error is logged or surfaced, the Asana PAT can be exposed to logs/observers and used for API impersonation.
Reviewed by Cursor Security Reviewer for commit 50180c1. Configure here.
| const slot = slots.allocate({ task_gid: task.gid, worktree_path: worktreePath, sim_udid: simUdid }) | ||
| log(` slot ${slot.slot_index}: metro ${slot.metro_port}, sim ${simUdid}`) | ||
|
|
||
| const r = spawnSync(`${DIR}/spawn-test-session.sh`, [ |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
This watcher launches unattended --yolo sessions and then auto-accepts the permissions-bypass dialog before injecting /one-shot --yolo from Asana task content.
Impact: anyone who can move/create tasks in the watched project can trigger autonomous privileged command execution on the runner without a human confirmation boundary.
Reviewed by Cursor Security Reviewer for commit 6f8419f. Configure here.
…t Metro never collides with DEBUG_<dep> dev-servers; build-and-test: DEBUG_ single-occupant port rule + /debugger cross-link; spawn-test-session: --resume mode (carries slot sim/Metro env); bump max_concurrent + sim_pool to 5
agent-watcher: - spawn-test-session: export ASANA_TOKEN + LANG + maestro PATH into sessions; enable --chrome (Claude-in-Chrome) for spawned agents. - session-watchdog: reap orphan Metros (cwd = deleted worktree); un-retire a done-asana session whose task moved off Complete (re-occupy its slot). - resume-task.sh (new): deterministic re-provision + --resume of a completed/stale task (fresh slot+sim+port, status off Complete); operator-only. - README: lifecycle steps for un-retire + re-provision. skills: - timeout.sh (new): portable timeout shim (gtimeout/perl fallback); bootstrap links it onto PATH. build-and-test/one-shot rules note timeout is available. - build-and-test: test-on-sim-by-default + verify-before-block-via-repro; maestro-flows-are-shortcuts (author task-specific flows); funded-test-accounts (rjqa2/rjqa3/test-funds); slot-sim-is-the-clone (master guard, trust the clone, no rebuild on false-negative); DEBUG_EXCHANGES allowDebugging trap. - select-ios-sim: refuse by-name resolution in slot mode (no master pollution). - ios-rn-build: cached path guards the Metro port + pins RCT_jsLocation to the slot. - asana-get-context / asana-task-update: fall back to credentials.json for the token. - one-shot: followup-reopens-status; test-on-sim reinforcement; timeout note.
…utes); add test-drives-the-real-action — complete the full core+gui implementation to a RUNNABLE app then execute the real end-to-end action to terminal success (don't stop at a quote/build), with a don't-over-wait-for-finality ceiling; gui-dependency-integration: gui-side wiring is mandatory work; one-shot: 'verified' = the real action executed, not a precursor
PR attachment + multi-repo structure: - spawn-test-session: export ASANA_GITHUB_SECRET into agent sessions (the missing piece — agents now attach PRs via the widget, not just comment). - asana-task-update: credentials.json fallback for the github secret; new --create-subtask (creates a per-PR subtask and re-points --attach-pr at it). - one-shot: attach-prs-by-default (was no-attach-default); multi-repo-subtasks (subtask per repo/PR, widget-attach each); dep-pr-draft-vs-bump (draft PR if beyond a version bump, comment+placeholder subtask if pure bump); finalize-gate excludes draft dep PRs from CI/bugbot gating. Sim bookkeeping (prior turn): - ensure-sim-pool: never recycle a sim a live claude-asana-<digits> session is on (reclaim it in_use instead) — fixes 'sim recycled out from under a live session'. - session-watchdog: un-retire re-reserves the session's actual sim/port in slots.json.
…ge-funds default login - build-and-test: references/sim-testing-playbook.md (funding floors, exhaustive account roster scoped against junk sim accounts, investigate-cheap-first, feature-enablement gotcha); maestro/common/ subflows (login-if-needed, dismiss-startup-modals, select-swap-pair, confirm-slider — slider solved once); funded-test-accounts: edge-funds (PIN 0000, holds HYPE) added + roster-only search scope + no-new-wallet-on-debug (SQLite crash); default YOLO login is edge-funds. - pr-create: pr-attach-screenshots.sh (Git Data API → agent-pr-assets branch → one inline-image PR comment) + attach-test-evidence rule/step; build-and-test proof-screenshots-for-pr; one-shot wiring incl. evidence-after-fix. - debugger: inject-and-capture made parallel-agent safe (per-slot DIAG_PORT/ paths, own-server-only cleanup). - agent-watcher: maestro MCP wired into spawns (maestro-mcp.json + --mcp-config); agent_model pin (claude-opus-4-8[1m]) config-driven; watcher verifies the one-shot prompt actually submitted (retry x3 — fixes the swallowed-prompt spawn); setup-task-workspace pins env.json YOLO login to edge-funds/0000.
| function capturePane(session) { | ||
| return sh(`tmux capture-pane -t "${session}" -p`) | ||
| } | ||
|
|
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: MEDIUM
listTargetSessions() accepts any tmux session name that only starts with claude-asana-, and later command paths interpolate that session name into shell command strings executed via execSync.
Impact: A crafted matching tmux session name containing shell-breaking characters can lead to command injection in watchdog execution paths.
Reviewed by Cursor Security Reviewer for commit b91332b. Configure here.
…ing back to direct-API proof
…visibility; add local-research workflow + skill
| } catch (e) { | ||
| console.error(`✗ Failed to determine changed files for lint: ${e.message}`); | ||
| return { success: false, failedStep: "lint (changed files)" }; | ||
| } |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: MEDIUM
baseRef from --base is interpolated directly into a shell command string in execSync (git diff ... ${baseRef}...HEAD ...) without argument-safe execution or strict ref validation.
Impact: If an attacker can influence --base, shell metacharacters in that value can trigger command execution in the verification runtime.
Reviewed by Cursor Security Reviewer for commit 82c806a. Configure here.
…eceipt capture hook + worktree husky fix
…y); ios-rn-build: start Metro on cached launches
… fix tracked in Asana 1215619633542395)
…ct bug in old piratechain module, agent-diagnosed in 1215619633542395)
…nce-before-PR; export AGENT_TASK_GID into sessions
…ned-phrase additions
…urtesy enders in external comms
…p scope defers to writing-style destinations; pr-address references it
… agent run reports; run-report template carries the no-slop guardrail
…ion or stated default
…egration test; sanctioned-roster spending is never a true-blocker; hook message pre-empts both
…age budgeted at 15 USD equivalent per run; blocked-ness requires an attempt
… lines); task-review: pointer-walk rule; setup-task-workspace: copy testconfig.json into worktrees; convention-sync: self-overwrite re-exec guard; memory: two-Mac topology + sfw install note
…ration, extract watch budget to watch-pr.sh; author: no-incident-narration + rationale-once
… in JSON, --force overrides); author: hypothetical examples in new principles
…r concurrent sim testing)
…release; one-shot: revive ping requires re-verifying outstanding waits against live process state
…s-assist vs decision-assist grading)




edge-dev-agents
Complete agent-assisted development workflow for Edge repositories:
slash skills, companion scripts, coding standards, review standards,
and meta-tooling for maintaining the workflow itself.
The distributable Cursor content lives under
.cursor/. This repo is theversioned home for those skills, rules, scripts, and docs.
The canonical local doc lives at
~/.cursor/README.md. During/convention-sync, that file is mirrored toedge-dev-agents/README.md, andthe repo copy should not keep a second
.cursor/README.md.Installation
Fresh machine (one command): clone this repo and run the bootstrap — it
installs everything (cursor skills/rules, the orchestration system, and shared
memories) into your home dir, seeds
credentials.jsonfrom the example, andlinks skills + shared memory:
For incremental onboarding instead of the full bootstrap:
1. Set the required env var in your
~/.zshrc:This drives branch naming and PR discovery across the workflow.
2. Sync the repo copy into
~/.cursor/:This repo treats
~/.cursor/as the canonical working copy. Use/convention-syncto move local changes intoedge-dev-agents, or run thecompanion script directly when onboarding:
~/.cursor/skills/convention-sync/scripts/convention-sync.sh \ --repo-to-user --stage3. Verify prerequisites:
ghCLI:gh auth loginjq:brew install jqASANA_TOKENenv var for Asana-backed workflowsTable of Contents
Orchestration & Memory
Beyond cursor skills/rules, this repo mirrors two more portable trees so a
second Mac is reproducible from a single clone +
./bootstrap.sh:agent-watcher/— the autonomous agent orchestration system (Asanawatcher daemon + worktree/iOS-sim pool helpers + watchdog). Canonical home is
~/.config/agent-watcher(XDG config;~/.agentsis not an establishedstandard). Committed: scripts,
*.js,asana-config.json,README.md,oom-repro/HANDOFF.md+scripts/, andcredentials.example.json. Nevercommitted:
credentials.json(secret) and machine-local state(
pool.json,slots.json,watchdog-state.json,*.state,*.log,oom-repro/forensics,oom-repro/logs).memory-shared/+bin/link-shared-memory.sh— cross-cutting Claudememory notes that should surface regardless of working directory. Canonical
home
~/.claude/memory-shared;link-shared-memory.shsymlinks them into theper-project auto-memory dirs (
~/.claude/projects/<project>/memory/) andmaintains a managed block in each
MEMORY.md. Claude auto-memory itself ismachine-local (per Anthropic docs) and is intentionally NOT synced — only the
shared store is. The only officially global Claude file is
~/.claude/CLAUDE.md(generated here from always-apply rules).
/convention-synckeeps all of the above in sync (home → repo);bootstrap.shdoes the reverse (repo → home) on a new machine.
Architecture
Separation of concerns:
SKILL.md) define workflows, rules, and step ordering..sh,.js) handle deterministic work like git,GitHub, Asana, and JSON processing.
.mdc) provide persistent guidance that gets loaded by context.together.
All GitHub API work uses
ghCLI. Deterministic git operations should live inscripts, not be re-described independently across skills.
Skills (Slash Skills)
Core Implementation
/im/one-shot/pr-create/dep-pr/changelogPlanning and Context
/asana-plan/task-review/qReview and Landing
/pr-review/pr-address/pr-land/staging-cherry-pickAsana and Utility
/asana-task-update/standup/chat-audit/convention-sync~/.cursor/with this repo, mirror the local README to repo root, and update PR descriptions fromREADME.md/author/fix-eslintCompanion Scripts
PR Operations
pr-create.shgh pr createpr-address.shgh apiREST + GraphQLgithub-pr-review.shgh pr view+gh apigithub-pr-activity.shgh api graphqlPR Landing Pipeline (
/pr-land)pr-land-discover.shpr-land-comments.shgit-branch-ops.shpr-land-prepare.shpr-land-merge.shpr-land-publish.shpr-land-extract-asana-task.shupgrade-dep.shdevelopfirst.staging-cherry-pick.shstagingverify-repo.shBuild, Lint, and Analysis
lint-commit.shlint-warnings.shinstall-deps.shcursor-chat-extract.jsAsana and Portability
asana-get-context.shasana-task-update.shasana-create-dep-task.shasana-whoami.shconvention-sync.sh~/.cursor/andedge-dev-agentsin either direction, mirroring~/.cursor/README.mdto repo rootREADME.mdgenerate-claude-md.sh~/.claude/CLAUDE.mdfrom always-apply rulestool-sync.shport-to-opencode.shShared Modules
edge-repo.jsghhelpers for thepr-landpipelineRules (
.mdcfiles)workflow-halt-on-error.mdcload-standards-by-filetype.mdcanswer-questions-first.mdcno-format-lint.mdctypescript-standards.mdcreview-standards.mdceslint-warnings.mdcafter_each_chat.mdcDesign Principles
work belongs in shared scripts.
ghover raw GitHub HTTP calls. Use the authenticated CLI for GitHubworkflows.
should live in one script and be consumed by multiple skills.
evaluating lint/type failures.
script instead of patching around it in an ad-hoc way.
~/.cursor/is the working source of truth;edge-dev-agentsis the distribution and review copy.