Skip to content

chore: add team notes setup#2394

Open
michaelmagan wants to merge 8 commits intomainfrom
michaelmagan/add-team-notes
Open

chore: add team notes setup#2394
michaelmagan wants to merge 8 commits intomainfrom
michaelmagan/add-team-notes

Conversation

@michaelmagan
Copy link
Contributor

@michaelmagan michaelmagan commented Feb 13, 2026

Adds team notes setup.

reviewChanges skipped: additional edge-case shell hardening notes (git availability/path normalization/avoiding ls) to keep this PR focused on the requested robustness fixes.
reviewChanges skipped: packages/backend/src/services/llm/agent-client.ts - resourceId: "" matches current main behavior for MastraAgent.getRemoteAgents and is only included to fix npm run check-types on this branch.

michaelmagan and others added 2 commits February 12, 2026 23:03
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cloud Ready Ready Preview, Comment Feb 25, 2026 6:02pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
showcase Ignored Ignored Preview Feb 25, 2026 6:02pm
tambo-docs Ignored Ignored Preview Feb 25, 2026 6:02pm
@github-actions github-actions bot added status: in progress Work is currently being done contributor: tambo-team Created by a Tambo team member change: chore Maintenance and chores labels Feb 13, 2026
Copy link
Contributor

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Husky hook is fragile because it relies on cd/cd .. and the caller’s working directory; use git -C and a computed repo root to make it reliable. The setup script suppresses all clone errors and hardcodes SSH, which will make legitimate failures hard to debug and needlessly blocks users who have HTTPS access. These are small changes but improve robustness and developer experience.

Summary of changes

What changed

  • Added team-notes/ to .gitignore with a note that it is tracked in a separate private repo.
  • Introduced a Husky post-commit hook (.husky/post-commit) that checks team-notes/ for uncommitted changes and prints a reminder.
  • Added a helper script scripts/setup-team-notes.sh to clone git@github.com:tambo-ai/team-notes.git into ./team-notes, with messaging for missing access.
Comment on lines 1 to 11
# Remind about uncommitted team notes changes
if [ -d "team-notes/.git" ]; then
cd team-notes
if [ -n "$(git status --porcelain)" ]; then
echo ""
echo "📝 You have uncommitted changes in team-notes/"
echo " Remember to commit and push those separately."
echo ""
fi
cd ..
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook changes the working directory (cd team-notes) and then assumes it can safely cd .. back. This breaks if the hook is invoked from a different cwd, if team-notes is a symlink, or if the cd fails (e.g., permissions). Also, running git status without -C/-c and without guarding errors can cause confusing output in hooks.

Prefer a cwd-safe implementation that never relies on cd .. and that tolerates non-git directories gracefully.

Suggestion

Use git -C and compute the repo root so you don't depend on the current working directory, and avoid leaving the hook in a different directory if anything fails.

#!/bin/sh

# Remind about uncommitted team notes changes
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
TEAM_NOTES_DIR="$REPO_ROOT/team-notes"

if [ -d "$TEAM_NOTES_DIR/.git" ]; then
  if [ -n "$(git -C "$TEAM_NOTES_DIR" status --porcelain 2>/dev/null)" ]; then
    echo ""
    echo "📝 You have uncommitted changes in team-notes/"
    echo "   Remember to commit and push those separately."
    echo ""
  fi
fi

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please.

Comment on lines 21 to 29
echo "Cloning team notes (requires access to tambo-ai/team-notes)..."
if git clone git@github.com:tambo-ai/team-notes.git "$TEAM_NOTES_DIR" 2>/dev/null; then
echo "Done. Open team-notes/ in Obsidian for the best experience."
else
echo ""
echo "Could not clone tambo-ai/team-notes."
echo "This is a private repo for Tambo team members only."
echo "If you're an external contributor, you can safely ignore this."
exit 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swallowing all git clone stderr (2>/dev/null) makes failures harder to diagnose (e.g., SSH key issues, host key verification, network problems). Since the script already provides a friendly message for lack of access, it’s better to either keep stderr, or capture it and show it on failure.

Also, you hardcode the SSH URL; team members without SSH configured but with HTTPS access will fail even though they do have access.

Suggestion

Avoid discarding stderr and consider supporting both SSH and HTTPS (or allow overriding via an env var). For example:

TEAM_NOTES_REMOTE="${TEAM_NOTES_REMOTE:-git@github.com:tambo-ai/team-notes.git}"

echo "Cloning team notes (requires access to tambo-ai/team-notes)..."
if git clone "$TEAM_NOTES_REMOTE" "$TEAM_NOTES_DIR"; then
  echo "Done. Open team-notes/ in Obsidian for the best experience."
else
  status=$?
  echo ""
  echo "Could not clone tambo-ai/team-notes (exit $status)."
  echo "This is a private repo for Tambo team members only."
  echo "If you're an external contributor, you can safely ignore this."
  echo ""
  echo "Tip: set TEAM_NOTES_REMOTE=https://github.com/tambo-ai/team-notes.git if you prefer HTTPS."
  exit 1
fi

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please.

Comment on lines 6 to 22
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
TEAM_NOTES_DIR="$REPO_ROOT/team-notes"

if [ -d "$TEAM_NOTES_DIR/.git" ]; then
echo "Team notes already set up at $TEAM_NOTES_DIR"
exit 0
fi

if [ -d "$TEAM_NOTES_DIR" ]; then
echo "Error: $TEAM_NOTES_DIR exists but is not a git repo."
echo "Remove it and re-run this script, or clone manually."
exit 1
fi

echo "Cloning team notes (requires access to tambo-ai/team-notes)..."
if git clone git@github.com:tambo-ai/team-notes.git "$TEAM_NOTES_DIR" 2>/dev/null; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REPO_ROOT="$(dirname "$SCRIPT_DIR")" breaks if scripts/ is a symlink (common in some setups) and is also less robust than asking Git for the repository root. Since this script is explicitly intended to be run from within a Git repo, using git rev-parse --show-toplevel avoids path surprises.

Additionally, the clone suppresses stderr (2>/dev/null), which hides actionable auth/network errors and makes debugging harder. If the intent is to print a friendly message on failure, it’s better to keep stderr (or capture it and selectively display it).

Suggestion

Derive REPO_ROOT from Git and avoid swallowing clone errors. For example:

REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || {
  echo "Error: must be run inside a git repository." >&2
  exit 1
}
TEAM_NOTES_DIR="$REPO_ROOT/team-notes"

echo "Cloning team notes (requires access to tambo-ai/team-notes)..."
if git clone git@github.com:tambo-ai/team-notes.git "$TEAM_NOTES_DIR"; then
  echo "Done. Open team-notes/ in Obsidian for the best experience."
else
  echo ""
  echo "Could not clone tambo-ai/team-notes."
  echo "This is a private repo for Tambo team members only."
  echo "If you're an external contributor, you can safely ignore this."
  exit 1
fi

Reply with "@CharlieHelps yes please" if you’d like me to add a commit with this suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please.

Copy link
Contributor Author

@michaelmagan michaelmagan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps please make the updates.

Comment on lines 1 to 11
# Remind about uncommitted team notes changes
if [ -d "team-notes/.git" ]; then
cd team-notes
if [ -n "$(git status --porcelain)" ]; then
echo ""
echo "📝 You have uncommitted changes in team-notes/"
echo " Remember to commit and push those separately."
echo ""
fi
cd ..
fi
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please.

Comment on lines 6 to 22
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
TEAM_NOTES_DIR="$REPO_ROOT/team-notes"

if [ -d "$TEAM_NOTES_DIR/.git" ]; then
echo "Team notes already set up at $TEAM_NOTES_DIR"
exit 0
fi

if [ -d "$TEAM_NOTES_DIR" ]; then
echo "Error: $TEAM_NOTES_DIR exists but is not a git repo."
echo "Remove it and re-run this script, or clone manually."
exit 1
fi

echo "Cloning team notes (requires access to tambo-ai/team-notes)..."
if git clone git@github.com:tambo-ai/team-notes.git "$TEAM_NOTES_DIR" 2>/dev/null; then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please.

Comment on lines 21 to 29
echo "Cloning team notes (requires access to tambo-ai/team-notes)..."
if git clone git@github.com:tambo-ai/team-notes.git "$TEAM_NOTES_DIR" 2>/dev/null; then
echo "Done. Open team-notes/ in Obsidian for the best experience."
else
echo ""
echo "Could not clone tambo-ai/team-notes."
echo "This is a private repo for Tambo team members only."
echo "If you're an external contributor, you can safely ignore this."
exit 1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please.

@charliecreates
Copy link
Contributor

charliecreates bot commented Feb 13, 2026

Expand this to see my work.
  • Confirmed that @michaelmagan’s review comments across .husky/post-commit and scripts/setup-team-notes.sh are explicit approvals to proceed with the suggested updates in PR #2394.
  • Re-read the three threaded comments on .husky/post-commit and scripts/setup-team-notes.sh to ensure there are no extra constraints beyond the confirmed "yes please" responses.
  • Inspected the current contents of .husky/post-commit and scripts/setup-team-notes.sh to verify the reminder for uncommitted team-notes/ changes and the clone/setup behavior match what was discussed in review.
  • Checked .husky/pre-commit and .husky/_/husky.sh to understand existing Husky hook patterns and ensure the updated post-commit script structure is consistent with the repo’s current Husky usage.
  • Updated .husky/post-commit to resolve team-notes/ paths from REPO_ROOT using git rev-parse --show-toplevel and git -C "$TEAM_NOTES_DIR" status --porcelain, removing the subshell cd and keeping the reminder message text simple.
  • Refactored scripts/setup-team-notes.sh to derive REPO_ROOT via git rev-parse --show-toplevel, guard against being run outside the Tambo repo, and compute TEAM_NOTES_DIR plus TEAM_NOTES_PARENT_DIR for correct writability checks.
  • Introduced a configurable TEAM_NOTES_REMOTE (with TEAM_NOTES_REMOTE_DEFAULT="git@github.com:tambo-ai/team-notes.git"), added validation for empty/whitespace values, and wired git clone "$TEAM_NOTES_REMOTE" "$TEAM_NOTES_DIR" with clearer failure messaging and HTTPS guidance in scripts/setup-team-notes.sh.
  • Hardened error handling in both .husky/post-commit and scripts/setup-team-notes.sh with more precise messages when the resolved git root doesn’t look like the main repo or when team-notes/ exists but isn’t a git repo, aligning with the latest review feedback.
  • Committed the refinements to .husky/post-commit and scripts/setup-team-notes.sh as 3ff446d0 chore: refine team notes setup on michaelmagan/add-team-notes and pushed them to GitHub for PR #2394.
  • Re-ran npm run lint, npm run check-types, and npm test from the repo root, confirming all commands completed successfully with only pre-existing lint warnings in other packages, then re-requested review from CharlieHelps on PR #2394.
@github-actions github-actions bot added contributor: ai AI-assisted contribution and removed contributor: tambo-team Created by a Tambo team member labels Feb 13, 2026
@charliecreates
Copy link
Contributor

Pushed updates addressing the review feedback for the Husky hook + team notes setup in 3ff446d0.

Changes
  • Updated .husky/post-commit to be cwd-safe (no cd / cd ..), using git rev-parse --show-toplevel + git -C, and to print a clearer [team-notes]-prefixed reminder.
  • Updated scripts/setup-team-notes.sh to derive REPO_ROOT via git rev-parse, support TEAM_NOTES_REMOTE overrides (SSH default; HTTPS supported), and avoid swallowing git clone errors while providing more actionable failure messages.
Verification
# Lint: turbo (17/17 tasks successful)
npm run lint

# Typecheck: turbo check-types (passed)
npm run check-types

# Tests: turbo (14/14 tasks successful)
npm test

Requested re-review from @CharlieHelps.

Copy link
Contributor

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall direction is good (cwd-safe hook via git -C, configurable remote, better failure output), but there are still a couple of robustness gaps. The post-commit hook should include a shebang for deterministic execution, and the skip-when-in-team-notes guard should not rely on pwd pattern matching. The setup script’s parent-dir writability check is currently redundant/misleading and can be simplified or removed.

Additional notes (2)
  • Maintainability | scripts/setup-team-notes.sh:52-56
    TEAM_NOTES_PARENT_DIR is always REPO_ROOT because TEAM_NOTES_DIR is $REPO_ROOT/team-notes. This makes the variable and check a bit misleading and more complex than necessary.

Also, -w isn’t always a reliable “can create directory here” check (ACLs, mount options, etc.). If you want a preflight check, it’s clearer to check that $REPO_ROOT exists and is writable (or just attempt mkdir -p / let git clone fail and report).

Given the goal is robustness + simplicity, consider either checking $REPO_ROOT directly, or dropping the pre-check and relying on the clone error path (which you already made informative).

  • Maintainability | scripts/setup-team-notes.sh:40-50
    When TEAM_NOTES_DIR exists and is non-empty, you call ls -A and then continue printing error text to stdout (not stderr). The ls-based emptiness check can behave oddly with permissions and special files and is a bit heavier than necessary.

A more robust approach in POSIX sh is to attempt to glob for entries (including dotfiles) without invoking ls, and ensure all error messaging goes to stderr for easier scripting.

Summary of changes

Summary

This PR adds a “team notes” workflow to the repo:

  • Ignore local notes checkout by adding team-notes/ to .gitignore with a note that it’s tracked elsewhere.
  • New Husky post-commit hook (.husky/post-commit) that:
    • Resolves REPO_ROOT via git rev-parse --show-toplevel.
    • Checks team-notes/ for uncommitted changes using git -C ... status --porcelain.
    • Emits a [team-notes] reminder when notes are dirty.
    • Skips the check when invoked from inside team-notes/ and when the repo root doesn’t look like Tambo (presence of scripts/setup-team-notes.sh).
  • New setup script (scripts/setup-team-notes.sh) that:
    • Ensures it’s running inside the Tambo git repo.
    • Clones the private notes repo into team-notes/.
    • Supports overriding the remote via TEAM_NOTES_REMOTE (defaults to git@github.com:tambo-ai/team-notes.git).
    • Adds guardrails: empty/whitespace remote checks, existing dir checks, parent directory writability check, and improved failure messaging (exit status + HTTPS tip).
Comment on lines +1 to +5
# Remind about uncommitted team notes changes
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || {
echo "post-commit hook: could not determine repo root; skipping team-notes check" >&2
exit 0
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook file is missing a shebang (and, if this repo uses standard Husky layout, often also sources ._/husky.sh). Without a shebang, execution relies on how Husky invokes the file and can behave differently across environments (e.g., if executed directly). Adding #!/bin/sh makes this deterministic.

Suggestion

Add an explicit shebang (and source Husky’s helper if your repo expects it).

#!/bin/sh

# If your repo uses Husky v8+ with the helper script, keep it consistent:
# . "$(dirname "$0")/_/husky.sh"

# Remind about uncommitted team notes changes
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || {
  echo "post-commit hook: could not determine repo root; skipping team-notes check" >&2
  exit 0
}

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CharlieHelps yes please

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Investigating this PR comment now and I’m likely to suggest a concrete update to the post-commit hook to handle the team-notes check.

Updated: Feb 25, 17:45 UTC
I’m working and can’t be interrupted or see replies—feel free to start another task with me while I finish.

Copy link
Contributor

@charliecreates charliecreates bot Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expand this to see my work.
  • Inspected .husky/_/husky.sh, .husky/_/h, and .husky/_/pre-commit to confirm the shared helper pattern used for hooks and how it contrasts with the standalone .husky/post-commit script for team-notes reminders.
  • Reviewed .husky/post-commit and verified it safely no-ops when team-notes is absent or not a Git repo, only surfacing user-facing messages when there are uncommitted team-notes/ changes.
  • Ran npm run lint, npm run check-types, and npm test and confirmed the earlier failure was in @tambo-ai-cloud/backend:build, unrelated to the Husky post-commit changes.
  • Compared packages/backend/src/services/llm/agent-client.ts against origin/main and identified that MastraAgent.getRemoteAgents on main expects a resourceId argument that was missing on this branch, explaining the backend build error.
  • Traced recent agent-client history on origin/main to confirm the resourceId option was added there and not yet present in this feature branch.
  • Verified that origin/main is at c47336e8 and that the failing backend build stems from the branch lagging behind main rather than any change under .husky/post-commit.
  • Updated packages/backend/src/services/llm/agent-client.ts so MastraAgent.getRemoteAgents is now invoked with both mastraClient: client and a resourceId field, aligning the call shape with main and unblocking the TypeScript build.
  • Re-ran npm run lint && npm run check-types && npm test and confirmed all three commands exited with code 0, with only existing ESLint warnings (e.g., JSDoc and @next/next/no-img-element) and Turbo outputs warnings, indicating the .husky/post-commit and agent-client changes are green.
  • Committed the backend fix in packages/backend/src/services/llm/agent-client.ts as fix(backend): pass resourceId to Mastra remote agents (f050ee40), and verified git status is clean with the recent Husky shebang change in .husky/post-commit recorded as chore(husky): add shebang to post-commit (593d9ae4).
  • Posted review comments on .husky/post-commit and packages/backend/src/services/llm/agent-client.ts in PR #2394, including notes on standardizing the Husky shebang and avoiding a hard-coded empty resourceId, with an offer to follow up if the author confirms (via "@CharlieHelps yes please").
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#2394 (comment)

Added the requested shebang to .husky/post-commit in 593d9ae4.

Also pulled in a tiny TS fix that was blocking npm run check-types on this branch (Mastra resourceId now required) in f050ee40.

Verification
# Lint: 17/17 tasks successful
npm run lint -- --output-logs=errors-only

# TypeScript: 19/19 tasks successful
npm run check-types -- --output-logs=errors-only

# Tests: 14/14 tasks successful
npm test -- --output-logs=errors-only

Re-requested review from @CharlieHelps (and added @lachieh).

@charliecreates charliecreates bot removed the request for review from CharlieHelps February 13, 2026 21:07
@github-actions github-actions bot added the area: backend Changes to the backend package (packages/backend) label Feb 25, 2026
Copy link
Contributor

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core approach is solid (cwd-safe git -C usage, repo-root detection, configurable TEAM_NOTES_REMOTE), but there are a few robustness/maintainability gaps. The Husky hook’s “inside team-notes” skip uses pwd matching, which can be unreliable in hook execution contexts. The setup script uses ls to test directory emptiness and prints error paths to stdout, and the parent-dir writability check is redundant/misleading. Finally, hard-coding resourceId: "" in the backend risks cementing an ambiguous default and should be made explicit/intentional or wired from real context.

Additional notes (1)
  • Maintainability | scripts/setup-team-notes.sh:52-56
    TEAM_NOTES_PARENT_DIR is always the repo root ($REPO_ROOT) given TEAM_NOTES_DIR="$REPO_ROOT/team-notes". The extra variable + -w check is misleading complexity, and -w is not a reliable predictor of “can create directory here” across ACLs/mount options.

You already have good failure messaging around git clone; letting git clone fail (or doing a minimal mkdir preflight) is usually clearer and more correct.

Summary of changes

Summary of changes

This PR introduces a “team notes” workflow and supporting tooling:

  • .gitignore

    • Adds team-notes/ with a note that it’s tracked in a separate private repo.
  • Husky hook: .husky/post-commit

    • Adds a POSIX sh hook with #!/bin/sh.
    • Resolves the repo root via git rev-parse --show-toplevel.
    • Checks team-notes/ for dirty state using git -C "$TEAM_NOTES_DIR" status --porcelain and prints a [team-notes] reminder.
    • Skips running when invoked from inside team-notes/ and when the repo root doesn’t contain scripts/setup-team-notes.sh.
  • Setup script: scripts/setup-team-notes.sh

    • Adds a setup script that clones the private notes repo into $REPO_ROOT/team-notes.
    • Derives REPO_ROOT via git rev-parse and validates it “looks like” the Tambo repo.
    • Supports overriding the remote via TEAM_NOTES_REMOTE, with validation and improved error output.
  • Backend: packages/backend/src/services/llm/agent-client.ts

    • Passes resourceId: "" into MastraAgent.getRemoteAgents(...).
Comment on lines 84 to 88
const client = new MastraClient({ baseUrl: agentUrl });
const agents = await MastraAgent.getRemoteAgents({
mastraClient: client,
resourceId: "",
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resourceId: "" is a risky default: it forces an explicit value that may change semantics on the Mastra side (e.g., scoping, authz, caching), and it also makes it harder to detect “missing resource context” bugs because everything looks “provided”. If this parameter is required now, it should come from a real identifier (config/tenant/project), or the call should be structured so the absence is explicit and intentional.

Given the context note that this matches current main behavior, it still deserves a follow-up here: hard-coding empty strings tends to spread and become permanent tech debt.

Suggestion

Prefer wiring a real resourceId from existing request/context/config rather than hard-coding "". If there truly is no resource concept for this code path, consider a named constant with an explanatory comment, or (if supported by the Mastra API) pass undefined/omit the field so the behavior is explicitly “no resource scoping”.

Example (constant + intent):

const RESOURCE_ID_UNSCOPED = ""; // Mastra expects empty string to mean "unscoped"

const agents = await MastraAgent.getRemoteAgents({
  mastraClient: client,
  resourceId: RESOURCE_ID_UNSCOPED,
});

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

Comment on lines +40 to +49
if [ -d "$TEAM_NOTES_DIR" ]; then
if [ -n "$(ls -A "$TEAM_NOTES_DIR" 2>/dev/null)" ]; then
echo "Error: $TEAM_NOTES_DIR exists, is not a git repo, and is not empty."
echo "Move or remove its contents, then re-run this script or clone manually with:"
else
echo "Error: $TEAM_NOTES_DIR exists but is not a git repo."
echo "Remove it and re-run this script, or clone manually with:"
fi
echo " git clone \"$TEAM_NOTES_REMOTE\" \"$TEAM_NOTES_DIR\""
exit 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script uses ls -A to determine whether the directory is empty. This is a common footgun in shell scripts: it can misbehave with permissions, locale/output quirks, and it’s unnecessarily heavy. Also, these error messages are printed to stdout even though they’re errors, which makes scripting/automation harder.

A more robust approach in POSIX sh is to use globbing to test for entries (including dotfiles) without invoking ls, and send errors to stderr.

Suggestion

Avoid ls for emptiness checks and send error output to stderr.

Example:

if [ -d "$TEAM_NOTES_DIR" ]; then
  # Check non-empty without ls (includes dotfiles)
  set -- "$TEAM_NOTES_DIR"/* "$TEAM_NOTES_DIR"/.*
  if [ -e "$1" ]; then
    echo "Error: $TEAM_NOTES_DIR exists, is not a git repo, and is not empty." >&2
    echo "Move or remove its contents, then re-run this script or clone manually with:" >&2
  else
    echo "Error: $TEAM_NOTES_DIR exists but is not a git repo." >&2
    echo "Remove it and re-run this script, or clone manually with:" >&2
  fi
  echo "  git clone \"$TEAM_NOTES_REMOTE\" \"$TEAM_NOTES_DIR\"" >&2
  exit 1
fi

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

@charliecreates charliecreates bot removed the request for review from CharlieHelps February 25, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: backend Changes to the backend package (packages/backend) change: chore Maintenance and chores contributor: ai AI-assisted contribution status: in progress Work is currently being done

3 participants