Skip to content

feat(init): run a team setup script declared as scripts.postInit (Tencent#1012) - #9

Closed
hsuchifeng wants to merge 1 commit into
mainfrom
claude/jeffr2026-issue-1012
Closed

hsuchifeng wants to merge 1 commit into
mainfrom
claude/jeffr2026-issue-1012

Conversation

@hsuchifeng

Copy link
Copy Markdown
Owner

Summary

Implements Tencent#1012. scripts.postPull runs headless, so a team whose MCP servers need a personal token has no step a new member sees: teamai init ends and the token is still unset. This adds scripts.postInit:

scripts:
  postInit:
    path: scripts/setup-env.mjs
  • teamai init (git and single-repo mode) runs it once with the terminal attached (stdio: inherit, no time limit), after the local config and hooks are in place and before the closing pull, so what the script collects (say, through teamai env set) is delivered by that same pull. In single-repo mode, which has no closing pull, init runs one mcp inject after the script.
  • The script gets TEAMAI_REPO and TEAMAI_SCOPE (user / project). The same containment as postPull applies (assertSafePath): a path resolving outside the clone is rejected with a warning. A non-zero exit is a warning naming the command below, never a failed init.
  • Without a terminal (isInteractive(): stdin not a TTY, CI, TEAMAI_NONINTERACTIVE) init skips it and prints Team setup script <path> needs a terminal and was not run. Run it later with \teamai script run postInit`.`
  • New teamai script run postInit (src/script-cmd.ts): runs the script for the scope governing the cwd, whether or not there is a terminal, then one MCP sync (mcpInject); exits with the script's code when it fails. Honors --dry-run (listed in DRY_RUN_PREVIEW).
  • An older CLI reads the same teamai.yaml and ignores the key (the scripts object already strips unknown entries).
  • Docs: "Post-init script" section in docs/usage-guide.md and docs/usage-guide.zh-CN.md; commands.md regenerated.

Not done from the issue text: --yes is not an init flag today, so it is not a skip trigger; the three existing non-interactive signals are.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature causing existing behavior to change)
  • Documentation only
  • Refactor / internal cleanup

Test Plan

  • npx tsc --noEmit passes
  • npm run lint passes
  • npx vitest run — full unit suite (the dry-run guard's "classifies every command" and commands-reference cover the new command)
  • Real-CLI e2e, npm run build && npx vitest run --config vitest.e2e.config.ts src/__tests__/e2e/post-init-script-1012.test.ts → 3/3 passed, against a bare git provider remote in a sandbox HOME (Cursor), with a team that declares SETUP_TOKEN in env/secrets.yaml, an MCP server using ${SETUP_TOKEN}, and a scripts/setup-env.mjs that prompts for the token and runs teamai env set SETUP_TOKEN --stdin:
    1. teamai init <url> --provider git --scope user --agent cursor --force with a piped stdin exits 0, prints the "needs a terminal and was not run … teamai script run postInit" line, and the MCP server waits (setup-api: SETUP_TOKEN is not set)
    2. teamai script run postInit with the answer on stdin: the script sees TEAMAI_REPO = the clone and TEAMAI_SCOPE=user, stores the token, MCP inject: follows and ~/.cursor/mcp.json carries the resolved header; the token is not in the output
    3. path: ../outside.mjs → Team setup script ../outside.mjs was not run: … and nothing runs
    4. a script exiting 3 → script run exits 3 with … exited 3. Run it again with \teamai script run postInit`.` and no MCP sync

Related Issues

Implements Tencent#1012

Notes for Reviewers

Independent of the Tencent#1011 PR: the e2e uses a key declared in env/secrets.yaml, which teamai env set already accepts on main. The init path that runs the script interactively (TTY) is exercised by script run in the e2e, since no test can own a terminal; init's own call is the same function with explicit off.


Generated by Claude Code

`teamai.yaml` can declare `scripts.postInit`, a Node entrypoint `teamai
init` runs once with the terminal attached, after the local config and
hooks are in place and before the closing pull, so what it collects
(`teamai env set`) is delivered by that pull. It is skipped without a
terminal, with the command to run later; `teamai script run postInit`
runs it again and then syncs MCP servers. Same path containment as
postPull; a failing script never fails init.
@hsuchifeng hsuchifeng self-assigned this Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

Code Erosion Report

Informational — never blocks the merge. scb-check==0.2.0 SlopCodeBench metrics; method & caveats in docs/ci-code-erosion.md.

Metric Value Human band Agent band Reading
Verbosity* 0.073 0.15 0.33 human
Erosion 0.685 0.31 0.68 agent
Cognitive erosion 0.867 – – –

Scanned 306 files / 60714 SLOC · high-CC functions 420/4841

* On TypeScript, verbosity is partial and the bands are Python-calibrated.

Rule hits (TS verbosity layer)

Standalone ast-grep, separate from the number above.

Rule Hits
unnecessary-else-after-return 32
empty-catch-block 5
redundant-ternary-same 1

38 distinct lines flagged across src/.

Copy link
Copy Markdown
Owner Author

CI note on the Codex PR Review check: it fails before the review starts (codex-action cannot read /home/runner/.codex/<run-id>.json, "Failed to read server info"), which is the action's local proxy not coming up because this fork has no OPENAI_API_KEY / OPENAI_RESPONSES_API_ENDPOINT repository secrets. It fails the same way on every PR here and touches nothing in this diff, so there is no fix to port into the branch; it needs the secrets on the fork, or the review run on Tencent/teamai-cli.


Generated by Claude Code

@hsuchifeng
hsuchifeng force-pushed the claude/jeffr2026-issue-1012 branch from 7e98c8a to 6a7526e Compare October 9, 2026 15:08
@hsuchifeng hsuchifeng closed this Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant