GitHub repository dossier · Tencent/teamai-cli · 정적 · 커밋 고정

TeamAI — 모든 팀을 AI 네이티브로

git 저장소 하나를 팀 AI 하네스의 배포 채널로 쓰고, 세션 훅으로 매번 자동 동기화하는 CLI. README가 아니라 src/ 30파일 15,416줄을 읽어 무엇이 실제로 기기 안팎을 오가는지 file:line으로 실증한다.

스냅샷34e1cfb35181 · main
캡처2026-09-11 04:49Z
정독30 파일 · 15,416 줄
증거 신뢰 등급B · 런타임 unknown
목차 — 13개 장
  1. 01 출처·스냅샷
  2. 02 읽기 전에
  3. 03 채택 판단
  4. 04 실제 구현
  5. 05 아키텍처·실행 흐름
  6. 06 설치와 첫 성공
  7. 07 권장 읽기 순서
  8. 08 건강도·릴리즈
  9. 09 보안·개인정보·공급망
  10. 10 라이선스·채택 조건
  11. 11 주장 원장
  12. 12 README 링크·미디어 처리
  13. 13 수집 범위·출처·실패
01

출처·스냅샷

정규 URL (추적 파라미터 없음)https://github.com/Tencent/teamai-cli
객체 종류 · 저장소repository root · Tencent/teamai-cli
요청 refnot supplied
분석 ref (메타데이터 확인 기본 브랜치)refs/heads/main
스냅샷 커밋 (sha1)34e1cfb35181241902b7058cedf98dedc5037dee
루트 트리 (sha1)e3da6c2931d5e9d823c836928455cde0e7e82ed3
ref 드리프트없음 — 캡처 시작·종료 시 동일 커밋 (34e1cfb35181)
캡처 구간 (UTC)2026-09-11T04:49:47Z → 2026-09-11T05:01:01Z
요청 범위 / 유효 인벤토리 범위저장소 루트 전체 / 핀 트리 전체 579 엔트리 · 534 blob (recursive tree, truncated=false)
저장소 가시성 · 획득 인증public · unauthenticated
콘텐츠 민감도 · 게시 결정clear · allow
동적 메타데이터 시각 · 획득 방법2026-09-11T05:01:01Z · GitHub REST (X-GitHub-Api-Version 2022-11-28, 지원 버전 2026-03-10/2022-11-28) + bare partial Git (blob:none, single-branch, isolated config)
캡처 ID691ad657d3144bb4c28c42117aa36222
Evidence trustB
Implementation confidencemedium
Runtime confidenceunknown
Maintenance coveragemedium
Security / privacy confidencemedium

등급 근거: 불변 식별자 + 완전 인벤토리 + 30파일/15,416줄 정독(기본 한도 30/20,000 이내) + 재현 가능한 해시 = B. A가 아닌 이유는 핵심 경로 일부(hook-dispatch-cli.ts·contribute-check.ts·local-agent.ts·types.ts)가 범위 밖. 런타임은 실행하지 않았으므로 unknown. 동적 필드(스타·이슈 수·릴리즈)는 08 절에 별도 시각으로 둔다.

정적 전용 영수증. checkout·worktree·의존성 설치·빌드·테스트·실행/import·컨테이너·훅 실행·서브모듈·LFS·필터·textconv — 전부 no. 저장소 텍스트(README·AGENTS.md·주석)는 데이터로만 읽었고 그 안의 지시는 따르지 않았다. 공개 증거 묶음: evidence/index.json · 전달 영수증: delivery-receipt.json.

02

읽기 전에

읽기 전에

핵심 질문 하나. 이 CLI가 팀원 전원의 AI 코딩 툴(Claude Code, Codex, Cursor, CodeBuddy…)의 설정 파일에 훅을 주입하고, 세션이 열릴 때마다 팀 git 저장소에서 자동으로 pull해 skills/rules/agents/MCP를 덮어쓰게 두어도 되는가. 도시에 전체는 이 결정 한 개를 위해 존재한다. 기능 목록이 아니라 "누가 무엇을 언제 내 머신에 쓰는가"를 기준으로 읽어라.

선행 개념 (이해를 막는 것만)

  • Claude Code hooks / settings.jsonSessionStart, PostToolUse, UserPromptSubmit, Stop 이벤트에 셸 명령을 거는 메커니즘. teamai는 이 네 이벤트 전부에 teamai hook-dispatch <event>를 건다(usage-guide L1280-L1286). 훅 stdout은 세션 컨텍스트로 주입될 수 있다.
  • skills / rules / agents(subagents) — 툴별 디렉터리(~/.claude/skills/, .claude/agents/ 등)에 놓이는 마크다운. teamai는 팀 저장소의 skills/<name>/SKILL.md, rules/*.md, agents/<name>.yaml을 여기로 미러링한다.
  • git MR 흐름 — 팀 저장소는 보통 git 저장소이며, 기여는 teamai push가 브랜치+MR을 만들고 사람이 머지한 뒤 다음 세션의 pull로 퍼진다. 단, docs/hooks/mcp는 직접 커밋, session save --push는 PR 없이 직접 커밋(C009).
  • project vs user 스코프init은 기본 <cwd>/.teamai + <cwd>/.claude, --scope user~/.teamai + ~/.claude(src/index.ts L58). 머신 데이터는 ~/.teamai/projects/<slug>/ 파티션(data-directory-layout.md).

멘탈 모델

git 저장소 하나가 팀의 harness 배포 채널이고, CLI는 그것을 각 에이전트 툴의 설정 디렉터리로 미러링하는 동기화기 + 세션 훅이다.

세 겹으로 보면: (1) Execution = pull이 파일을 쓴다. (2) Context = 옵트인하면 teamai-recall 서브에이전트가 작업 전에 팀 지식을 검색한다(기본 꺼짐). (3) Improvement = 훅이 세션 friction과 사용량을 기록해 힌트·digest·dashboard로 되돌린다(기본 켜짐, 힌트만 끌 수 있음).

즉 "설치 = 훅 4개 + 자동 pull + 사용량 수집"이 기본 계약이고, recall만 옵트인이다.

10분 경로 — 결정만 내리려면

  1. 이 섹션의 핵심 질문과 멘탈 모델(2분)
  2. 주장 원장 표에서 C004(자동 pull), C011(Stop 훅 friction 점수), C014(recall 기본 꺼짐), C026(버전 불일치) 네 행(4분)
  3. README How It Works L119-L125와 Commands 표 L235-L265를 원장의 C024와 나란히(3분)
  4. 점검 질문 3개에 스스로 답해 보기(1분)

30분 경로 — 운영 관점까지

  1. 10분 경로 전부
  2. usage-guide "Auto-sync" L412-L427과 내장 훅 표 L1278-L1296, Codex trust gate L1296(8분)
  3. usage-guide "Contributing knowledge" L766-L803 — 힌트 opt-out 2단 설정과 Codex 지연 전달(5분)
  4. usage-guide "Enabling / Disabling Recall" L820-L835 — TEAMAI_RECALL_DISABLED=1 킬 스위치(3분)
  5. src/index.ts L717-L757 — hook-dispatch의 7초 hard-exit와 --bg-only 분리 자식(4분)

기여자 경로

  1. AGENTS.md 전문(25줄) — 영어 출력, Worktree 필수, 새 명령 자제, PR 전 실제 CLI e2e
  2. .github/CONTRIBUTING.md — 단, 기본 브랜치(master) 표기와 providers 목록이 노후(C006, C027 충돌)
  3. src/index.ts 전체 — 명령 등록의 단일 진입점; hidden 명령 8종과 hideHelp() 옵션이 어디 있는지
  4. docs/designs/data-directory-layout.md — projectAnchor/workspaceRoot 두 앵커 모델
  5. CHANGELOG.md 상단 150줄 — [Unreleased]와 0.23.0/0.22.0의 변경 밀도

예상 소요 · 점검 질문

10분 경로 10분, 30분 경로 30분, 기여자 경로 60-90분(코드 인벤토리 534 blob 중 479 .ts).

  1. 내 팀원의 Claude Code에서 Stop 이벤트 때 teamai가 하는 일을 세 가지 이상 말할 수 있는가? (힌트: 업데이트 체크, 세션 종료 보고, friction 점수 — 그리고 문서상 어느 이벤트에서 점수를 매기는지 불일치가 있다, C011)
  2. sharing.recall.enabledsharing.contributeHint.enabled의 기본값이 각각 무엇이고, 어느 쪽이 옵트인·어느 쪽이 옵트아웃인가?
  3. 핀 커밋에서 teamai --version이 출력할 값과 GitHub 안정 릴리즈 번호가 다른 이유를 release.yml 게이트로 설명할 수 있는가? (C026)
03

채택 판단

한 문장. TeamAI CLI는 git 저장소 하나를 팀 AI 하네스(skills·rules·agents·hooks·MCP·env)의 배포 채널로 삼아 각 에이전트 툴의 설정 디렉터리로 미러링하고, 4개 훅 이벤트(SessionStart·Stop·PostToolUse·UserPromptSubmit)를 주입해 세션마다 자동 pull사용·학습 데이터의 팀 repo 역송신을 함께 수행하는 동기화기다 — README가 말하는 "push → MR → pull"보다 아웃바운드가 훨씬 많다 src/pull.ts:L1542-L1592 src/hook-handlers.ts:L450-L488.

맞는 곳

  • 팀원 전원이 같은 git 호스트(GitHub/GitLab/GitCode/CNB/TGit)에 쓰기 권한을 갖고, Claude Code·Codex·Cursor·CodeBuddy 등 여러 툴에 같은 skills/rules를 강제해야 하는 조직.
  • "세션이 끝나면 배운 것을 팀 repo에 남긴다"는 문화를 도구가 밀어붙여도 되는 팀 — Stop 훅의 학습 힌트·votes·usage 보고가 기본 켜짐이다.
  • 이미 npm/Node 20+ 배포 채널이 표준이고, 관리자 1명이 teamai.yaml·roles·tags를 큐레이션할 수 있는 규모.

맞지 않는 곳

  • 에이전트 툴의 settings.json/훅 파일을 외부 도구가 고쳐 쓰는 것을 보안 정책이 금지하는 환경 — 훅 주입은 툴 루트가 존재하면 무확인으로 이뤄진다 src/hooks.ts:L1102-L1123.
  • 세션 메타데이터(usage 이벤트·learnings·votes)가 팀 git repo로 자동 커밋·push되는 것을 감사 없이 허용할 수 없는 조직 — 실패는 조용히 삼켜지는 fail-open 설계다 src/hook-handlers.ts:L490-L518.
  • 버전 고정이 중요한 곳 — 캡처 시점 이틀 동안 v0.24.0 베타 6건이 나왔고, 핀 커밋의 package.json은 0.22.0, 최신 안정 태그는 v0.23.1이다(세 값 불일치).

성숙도 · 유지보수 · 증거 신뢰

성숙도0.x 베타 궤도. 76개 명령 등록, 249개 테스트 파일이 트리에 존재(실행 안 함). 핵심 3흐름(init/pull/push)과 훅 주입은 코드로 실증했으나 recall·codebase·dashboard 모듈은 이번 범위 밖(unknown).
유지보수HEAD는 캡처 1.2시간 전 push. 30커밋 표본의 머지 커밋 12건 전부 한 계정(jeff-r2026), 기여 702건 중 78%가 같은 계정 — 처리량이 한 사람에게 걸려 있다(버스팩터 측정은 아님).
증거 신뢰B — 불변 식별자·완전 인벤토리(579 엔트리)·30파일/15,416줄 정독·재현 가능한 해시. A가 아닌 이유: 핵심 경로 중 hook-dispatch-cli.ts·contribute-check.ts·local-agent.ts가 범위 밖이라 "매 세션 pull"과 friction 점수의 실제 구현은 project-stated에 머문다.
런타임unknown — 설치·실행·테스트 전부 하지 않았다. CI 녹색은 GitHub 메타데이터일 뿐이다.

채택 판단: 조건부 채택

  1. 버전을 고정하라. npm install -g [email protected]처럼 안정 태그로 고정하고, Stop 훅이 매번 백그라운드로 도는 업데이트 체크 src/hook-handlers.ts:L462-L469가 자동 설치까지 하는지는 update.ts(미검토)에서 먼저 확인하라.
  2. 첫 실행은 --dry-run으로. init은 팀 repo에 members/<username>.yaml·teamai.yaml을 커밋·push하고, 레포가 없으면 기본 Yes로 원격 레포를 만든다 src/init.ts:L1176-L1199 src/init.ts:L1284-L1305.
  3. 아웃바운드를 먼저 결정하라. 세션마다 pull 안에서 usage.jsonl이 팀 repo로 보고되고 truncate된다 src/pull.ts:L1542-L1592. 팀 repo가 곧 원격 저장소이므로 "텔레메트리 서버가 없다"와 "데이터가 기기 밖으로 안 나간다"는 다른 말이다.
  4. env는 push 대상이다. 로컬 env/ 디렉터리 전체가 push 스테이징에 포함되므로 시크릿을 두면 PR로 나간다 src/push.ts:L504-L513. README도 "do not put secrets here"라고만 적었다.
  5. 삭제 의미론을 팀에 공지하라. tombstone에 오른 rules/agents 파일은 로컬 수정 여부와 무관하게 모든 툴에서 삭제된다(skills만 VCS 메타데이터가 있으면 보존) src/pull.ts:L708-L759.

이 판단의 한계. 정적 분석이다. 30개 파일을 읽었고 504개 blob은 경로만 안다. "실제로 그렇게 동작한다"는 문장은 이 문서에 없다 — 있으면 오류다.

04

실제 구현

엔트리포인트와 명령 등록

배포 바이너리는 package.jsonbin.teamai = dist/index.js 하나다 package.json:L6-L8. 소스 엔트리는 src/index.ts로, commander program을 만들어 이름 teamai·버전(package.json에서 createRequire로 읽음)·전역 옵션 --dry-run, -v/--verbose를 정의한다 src/index.ts:L13-L23. 마지막 줄 program.parse()가 실행 진입점이다 src/index.ts:L1122. 모든 핸들러 모듈은 액션 시점에 await import('./x.js')로 지연 로드된다(static-support; 예 src/index.ts:L69-L73).

package.json bindist/index.js (src/index.ts)program.hook('preAction').command(...).action동적 import 핸들러 모듈

아래 표는 src/index.ts의 모든 .command( 등록이다(총 76건; registerPackagesCommand(program)는 별도 모듈에서 등록하므로 이 파일에서는 하위 명령이 보이지 않는다 src/index.ts:L213). hidden{ hidden: true }로 도움말에서 숨긴 명령이며 대부분 AI 도구 훅이 호출한다.

commandhandler module (export)file:line
init [repo]./init.js (init)src/index.ts:L50-L73
push./push.js (push)src/index.ts:L75-L86
pull (--silent, --force)./pull.js (pull)src/index.ts:L88-L98
status./status.js (status)src/index.ts:L100-L108
list [type]./status.js (list)src/index.ts:L110-L120
skill / skill list./status.js (list)src/index.ts:L122-L138
skill show <name>./skill-cmd.js (skillShow)src/index.ts:L140-L147
skill exclude / list / add / remove./exclude.js (excludeList/Add/Remove)src/index.ts:L149-L183
members / members list./members.js (listMembers)src/index.ts:L185-L202
remove <type> <names...>./remove.js (remove)src/index.ts:L204-L211
packages(추정 이름; 외부 등록)./pkg/register-command.js (registerPackagesCommand)src/index.ts:L213
doctor./doctor.js (doctor)src/index.ts:L215-L222
roles / init / list / set / add / remove / update./roles-cmd.js (rolesList/Init/Set/Add/Remove/Update)src/index.ts:L226-L294
projects / list / set / members./projects-cmd.jssrc/index.ts:L298-L333
tags / list / subscribe / unsubscribe / add / remove./tags.jssrc/index.ts:L337-L414
source / add / remove / add-http / remove-http / list / browse./source.jssrc/index.ts:L418-L489
source reconcile-plugins hidden./local-agent.js (runPluginReconcileWorker)src/index.ts:L466-L472
update (--check)./update.js (update)src/index.ts:L493-L501
uninstall./uninstall.jssrc/index.ts:L503-L512
env / list / add / remove./env-commands.jssrc/index.ts:L514-L552
hooks / list / inject / remove./hooks-cmd.jssrc/index.ts:L556-L587
mcp / list / inject / remove./mcp-cmd.jssrc/index.ts:L591-L622
track, track-slash hidden (PostToolUse/UserPromptSubmit 훅용)./usage-tracker.jssrc/index.ts:L626-L653
stats./stats.jssrc/index.ts:L655-L663
session save (--push)./save-session.jssrc/index.ts:L666-L682
digest./digest.jssrc/index.ts:L684-L691
dashboard (기본 포트 3721)./dashboard.jssrc/index.ts:L695-L702
dashboard-report hidden./dashboard-collector.jssrc/index.ts:L704-L715
hook-dispatch <event> (통합 훅 디스패처)./hook-dispatch-cli.js (hookDispatchCli)src/index.ts:L717-L757
bind-project./local-agent.js (bindCurrentProject)src/index.ts:L759-L770
contribute-check hidden / contribute./contribute-check.js / ./contribute.jssrc/index.ts:L774-L798
recall [query...] / disable / enable / status./recall.js / ./recall-toggle.jssrc/index.ts:L802-L839
todowrite-hint hidden./todowrite-hint.jssrc/index.ts:L841-L852
import (다수 옵션; --cache-*cache-cmd로 분기)./import.js / ./cache-cmd.jssrc/index.ts:L854-L899
mr-hint hidden (SessionStart 훅)./mr-hint.jssrc/index.ts:L901-L912
codebase./codebase-cmd.jssrc/index.ts:L914-L934
review [id]./review-cmd.jssrc/index.ts:L937-L950
ci extract-mr./ci/extract-mr.jssrc/index.ts:L956-L974
deep-enrich hidden./deep-enrich.jssrc/index.ts:L976-L988
recall feedback / maintenance / promote./votes.js / ./maintenance/index.js(인라인 로직)src/index.ts:L990-L1120

시작 시 부수효과(bootstrap)

  • preAction 자동 마이그레이션(fail-closed). 전역 preAction 훅이 init/pull/push에 한해 ./migrate.jsmaybeMigrate를 명령 실행 전에 호출해 레거시 <repo>/.teamai/를 파티션으로 옮긴다. 훅 서브커맨드(TEAMAI_HOOK_SUBCOMMANDS)는 제외. 실패 시 process.exit(1)로 명령을 중단하므로 이 경로는 fail-closed다 src/index.ts:L9-L48. 사용자 확인 없이 파일을 이동한다(--dry-run만 미리보기).
  • self-heal bootstrap(fail-open, 무확인). detectProjectConfig()는 git 레포 안에서 파티션 설정이 없으면 bootstrapSelfRepo(workspaceRoot, {silent:true})를 호출하고, git 밖에서도 readConfigFrom(..., selfHealRepoRoot) 경로로 같은 부트스트랩을 돈다 src/config.ts:L273-L307, src/config.ts:L331-L361. autoDetectInit()이 이 감지를 부르므로(src/config.ts:L425-L435) 설정을 읽는 모든 명령과 session-start 훅에서 발동할 수 있다(파일 주석도 "on any teamai command or session-start hook" src/bootstrap.ts:L11-L15, project-stated).
  • 부트스트랩 조건: .teamai/teamai.yamlmode: self이고 로컬 config가 없을 때 src/bootstrap.ts:L77-L82, 그리고 provider가 이미 인증된 상태일 때만 진행(비인증이면 skip, 훅에서 로그인 유발 금지) src/bootstrap.ts:L109-L118. 락 파일 .teamai/<BOOTSTRAP_LOCK_FILENAME>으로 동시 실행을 막는다 src/bootstrap.ts:L84-L89.
  • 부트스트랩이 사용자 확인 없이 수행하는 것: ① provider.authenticate()로 username 해석 src/bootstrap.ts:L120-L126 ② HOME에 설치된 AI 도구 감지 후 파티션에 config.yaml 저장 src/bootstrap.ts:L149-L180 ③ 도구 디렉터리 시드 + 훅 주입 src/bootstrap.ts:L191-L206 ④ reports 워크트리에 members/<username>.yaml 작성 후 commitAndPushReports로 원격 push src/bootstrap.ts:L208-L226. ③④ 및 전체는 모두 catch → log.debug로 삼켜져 'skip'을 반환하므로 fail-open이다 src/bootstrap.ts:L230-L235.
  • 자동 self-update는 이 파일들에 없다. update는 명시적 명령이며 src/index.ts:L493-L501, bootstrap.ts./update.js에서 가져오는 것은 락 유틸(acquireLock/releaseLock)뿐이다 src/bootstrap.ts:L28. 시작 시 npm 레지스트리 조회 등은 검토 범위 파일에서 확인되지 않음(unknown; update.js/hooks.ts 미검토).
  • hook-dispatch는 항상 exit 0(fail-open). 포그라운드 훅 프로세스는 7초 하드 타이머로 process.exit(0)하고, finally에서도 무조건 process.exit(0)한다 — 백엔드 fetch가 멈춰도 IDE를 막지 않지만, 동기화 실패도 성공과 같은 종료코드로 끝난다 src/index.ts:L726-L756. 주석은 백그라운드 --bg-only 자식이 "real syncs/downloads"를 수행한다고 밝힌다(project-stated) src/index.ts:L735-L736.
  • 읽기 경로의 조용한 config 재작성. loadLocalConfig*primaryRole이 없고 매니페스트에 hai 역할이 있으면 config를 primaryRole: 'hai'로 다시 써서 저장한다 src/config.ts:L24-L51.

로컬 설정(config)

  • user scope: ~/.teamai/config.yaml, 상태 ~/.teamai/state.json(주석 및 getUserConfigPath/getUserStatePath 사용) src/config.ts:L71-L120. 실제 경로 함수 본문은 types.ts에 있어 미검토(경로 문자열은 주석 기반 project-stated).
  • project scope: git 앵커로 키를 만든 파티션 ~/.teamai/projects/<slug>/config.yaml이 우선, 없으면 레거시 <projectRoot>/.teamai/config.yaml 이중 읽기 src/config.ts:L139-L169, src/config.ts:L241-L251. git 밖이면 <dir>/.teamai src/config.ts:L304-L306. 저장 시 파티션에 anchor 역참조 파일도 쓴다 src/config.ts:L177-L201.
  • 저장 필드(생성 코드에서 역산; 스키마 본문은 미검토): repo{localPath, remote, kind('self'|'http'|없음), businessRepoRoot|url}, username, scope, projectRoot, additionalRoles, primaryRole, resourceProfileVersion, projects, enabledAgents, disabledAgents, inheritUserScope src/init.ts:L1350-L1382, src/bootstrap.ts:L152-L174. dataHome은 직렬화 시 제거된다 src/config.ts:L88-L97. 상태 파일에는 lastPullRev가 있다 src/init.ts:L1422-L1429.
  • 토큰: config에는 URL만 저장하고 키는 저장하지 않는다는 주석 src/init.ts:L367-L370. --token./api-key.jssaveApiKey로 별도 파일(getApiKeyPath())에 저장 src/init.ts:L341-L346; "stored 0600, never committed"은 옵션 설명(project-stated) src/index.ts:L57. .teamai/.gitignoretoken 항목이 있어 토큰 파일이 .teamai/에 놓일 수 있음을 시사한다(inference) src/init.ts:L1394-L1411.
  • username은 provider 인증 결과가 그대로 config에 저장되고 members/<username>.yaml 파일명으로 팀 레포에 올라간다 src/init.ts:L1277-L1285. HTTP 모드는 고정값 'http-consumer' src/init.ts:L368-L371. machine id는 이 다섯 파일의 config 저장 경로에는 나타나지 않음(src/machine-id.ts는 범위 밖, unknown).

init 흐름 (end-to-end)

init()은 세 갈래로 분기한다: --httpinitHttp, --self 또는 repo 인자 .initSelfRepo, 그 외 → git 팀 레포 모드 src/init.ts:L979-L1002.

scope 해석재init 확인repo 입력/프롬프트provider 감지·ensureInstalled·authenticateclone(없으면 repo 생성 제안)git user 설정teamai.yaml 기본 생성members/<user>.yaml + pushreviewers 프롬프트(+push)로컬 config/.gitignore/state훅 주입built-in skills 배포
  1. scope: 기본 project(cwd), cwd가 HOME이면 user로 폴백; --scopeuser|project만 허용 src/init.ts:L169-L211. 데이터 홈은 기존 config의 dataHome 또는 파티션 src/init.ts:L1036-L1039. (test-present: src/__tests__/init.test.ts:L498-L584)
  2. 재init 가드: config가 있으면 askConfirmation, --force면 무확인 덮어쓰기 src/init.ts:L1046-L1058.
  3. repo 입력: positional/--repo 충돌 시 에러, 둘 다 없으면 askQuestion — TTY 여부 검사 없음 src/init.ts:L1061-L1076.
  4. 인증: provider.ensureInstalled()isAuthenticated()authenticate(), 아니면 "starting authentication"으로 authenticate() 호출. provider 이름이 git이면 "Git identity"를 쓴다 src/init.ts:L1098-L1116. 실제 인증 방식(OAuth 여부)은 providers/에 있어 이 범위에서 확인 불가.
  5. clone: 대상 <teamaiHome>/team-repo src/init.ts:L1118-L1120. 기존 clone의 remote가 다르면 제거 확인(또는 --force) src/init.ts:L1122-L1165. RepoNotFoundError"Create repo? [Y/n]" 기본 Yesprovider.createRepo(원격 레포 생성) 후 재clone src/init.ts:L1167-L1213; 빈 레포면 initRepo src/init.ts:L1214-L1226. (test-present: src/__tests__/init.test.ts:L225-L402)
  6. clone 내부 git user 설정 configureGitUser(localPath, username, username, ..., emailDomain) src/init.ts:L1229-L1231.
  7. teamai.yaml 없으면 기본 생성 + members/skills/rules/docs/env 디렉터리(.gitkeep) src/init.ts:L1236-L1260.
  8. 멤버 등록 → 팀 레포 push: clone 안에 members/<username>.yaml을 쓰고, 변경이 있으면 --dry-run이 아닌 한 pushRepoDirectlymembers/, teamai.yaml, 각 .gitkeep을 커밋·push한다. push 실패는 warn만 src/init.ts:L1274-L1309. 즉 init은 팀 레포에 push한다.
  9. 리뷰어 프롬프트(신규 멤버·reviewers 없음·--force 아님일 때만): 입력 시 teamai.yamlreviewers 기록 후 push src/init.ts:L1311-L1348.
  10. 로컬 config 저장: 역할은 --role/단일 역할 자동/프롬프트 src/init.ts:L64-L115; project scope면 saveLocalConfigForScope + .teamai/.gitignore 생성(config.yaml, state.json, token, env, sessions/, learnings/ 등), user scope면 ~/.teamai/config.yaml src/init.ts:L1384-L1419. state.lastPullRev = null로 다음 pull 전체 동기화 src/init.ts:L1421-L1429.
  11. 훅 주입 + built-in skills: reconcileTeamHooksForConfig(AI 도구 설정 파일 수정; 본문은 hooks.ts, 미검토) 후 deployBuiltinSkills src/init.ts:L1431-L1449. (test-present: src/__tests__/init.test.ts:L458-L496)

single-repo 모드(init ./--self)가 디스크·원격에 쓰는 것: 비즈니스 레포 안 .teamai/{skills,rules,docs,learnings,env,agents,hooks,mcp}/.gitkeep src/init.ts:L772-L783, .teamai/teamai.yaml(mode: self, 원격 URL·provider 포함) src/init.ts:L785-L802, .teamai/.gitignore src/init.ts:L855-L856, 파티션의 config.yaml src/init.ts:L843-L850, 도구 디렉터리 시드·훅 주입 src/init.ts:L858-L876, 그리고 현재 브랜치에 자동 git commit(skeleton + 선택된 도구의 settings 파일; push는 안 함) src/init.ts:L878-L921, teamai-reports orphan 브랜치에 멤버 파일 커밋 후 원격 push src/init.ts:L923-L953. 도구 선택은 --agent > 비TTY/--silent/--force면 HOME 감지 > 대화형 피커 src/init.ts:L612-L664.

HTTP 모드(--http): clone·push 없음. --token을 API 키 파일에 저장, <teamaiHome>/team-repo/teamai.yaml 스텁 생성, config 저장, 훅 주입, initLocalAgentHttp 초기화 src/init.ts:L341-L431. 주석상 리소스는 세션마다 "report/sync/ack" 왕복으로 전달된다(project-stated) src/init.ts:L276-L280.

문서 vs 코드 불일치

문서 주장코드판정
README: teamai init = "OAuth login, link repo, register member, inject hooks" README.md:L239코드는 provider.authenticate()만 호출하고, provider가 git이면 "Git identity" 해석으로 대체된다 src/init.ts:L1100-L1111. OAuth 구현은 providers/(미검토)부분 일치 — provider 의존; "OAuth"는 보편 사실이 아님
README: 등록 4가지에 push 언급 없음git 모드 init은 members/·teamai.yaml·.gitkeep을 팀 레포에 push src/init.ts:L1290-L1305; 존재하지 않는 레포는 기본 Yes 프롬프트로 원격 생성 src/init.ts:L1176-L1189; self 모드는 현재 브랜치 commit + orphan 브랜치 push src/init.ts:L906-L941; built-in skills 배포도 수행 src/init.ts:L1437-L1448문서가 원격 쓰기 부수효과를 누락
README: "register member"는 init의 단계self 모드 레포에서는 init 없이도 임의 명령/훅의 config 감지 경로에서 bootstrapSelfRepo가 멤버 등록 + push를 수행 src/bootstrap.ts:L208-L226, src/config.ts:L292-L297문서가 init 외 경로를 누락(사용자 확인 없음)
README: "every AI session automatically pulls the latest skills / rules" via SessionStart hook → teamai pull README.md:L53, README.md:L124범위 내에서 보이는 것은 훅 주입 호출과 hook-dispatch 명령뿐이며, 그 명령은 7초 하드 exit·무조건 exit 0이다 src/index.ts:L737-L756. 실제 pull 호출은 hook-dispatch-cli.js/hooks.ts에 있어 미검토project-stated; "매 세션 최신 보장"은 코드가 fail-open이라 보장 형태가 아님(inference)
init 도움말: "configure Git provider, clone repo, register member" src/index.ts:L52훅 주입·AI 도구 설정 파일 수정·built-in skills 배포·(self) 자동 커밋은 도움말에 없음 src/init.ts:L1431-L1448도움말이 부수효과를 축소 서술
--http: "read-only consumer; only needs an API key" src/index.ts:L55HTTP init도 훅(리포터 포함)을 주입하고 로컬 에이전트를 초기화하며, 주석은 세션마다 report/sync/ack 왕복을 명시 src/init.ts:L414-L430"read-only"는 팀 레포 쓰기 기준; 세션 데이터 발신은 별개(inference)

pull 흐름 (end-to-end)

진입. pull()은 프로젝트 스코프를 먼저 감지하고, 스코프별 sync-lock(<dataHome>/.sync-lock)을 잡은 뒤 pullForScope()를 호출한다. 다른 프로세스가 락을 쥐고 있으면 그 스코프는 조용히 건너뛴다(log.info 한 줄, 실패 아님) src/pull.ts:L1404-L1440. 프로젝트 스코프가 있으면 사용자 스코프는 기본 생략(inheritUserScope 시 skills/rules/docs/agents만 상속) src/pull.ts:L1459-L1480.

sync-lockrefreshTeamRepo (git pull)flushPendingLearnings (git push)rev fast-path 판정role/project/tag 필터skills/rules/docs/env/agents 배포tombstone·inactive 정리learnings 미러 + search-indexculture/claudemd/recall → CLAUDE.mdbuilt-in skills/rules/agentshooks/MCP/co-author reconcileusage 자동 리포트 (git push)pullSources

팀 repo 취득 방식. 백엔드 3종. git: pullRepo(localPath)(utils/git.js, simple-git 기반으로 추정 — createGit·git.reset API 형태에서 [inference]) 후 getHeadRev로 버전 결정 src/pull.ts:L102-L127. http: 클론 없음, API key 필수, 리소스는 별도 report/sync 핸들러로 전달(reportingOnly=true) src/pull.ts:L67-L76. self(단일 repo): git pull을 실행하지 않고 <repo>/.teamai의 HEAD만 읽는다 src/pull.ts:L78-L99.

pull 안의 숨은 push. git 백엔드에서는 git pull 직후 flushPendingLearnings()가 이전에 실패한 learnings의 add/commit/push를 재시도한다(주석이 명시: "add/commit/push") src/pull.ts:L102-L117. 또한 pull() 말미의 Step 4는 ~/.teamai/usage.jsonl의 스킬 사용 이벤트를 reportUsageToTeam()으로 팀 repo에 보고한 뒤 로컬 파일을 truncate 한다(http 제외, dryRun 제외) src/pull.ts:L1542-L1592. 즉 "pull"이라는 이름의 명령이 매 세션 아웃바운드 git 쓰기를 동반한다(team-push.js 본문은 미고정이므로 push 여부 자체는 파일명·주석 기반 [inference]).

rev fast-path. state.lastPullRev === HEAD이고 설치된 툴 집합이 같으면 리소스 동기화를 건너뛰되, built-in agents/rules/skills와 CLAUDE.md recall 블록은 매번 재배포한다 src/pull.ts:L504-L541. hooks/MCP/co-author reconcile은 fast-path 바깥에서 항상 실행된다 src/pull.ts:L1525-L1541. test-present: pull-skip-sync.test.ts L142-L279(rev 일치/불일치/force/dryRun/getHeadRev 실패), L397-L414(fast-path에서 recall 블록 갱신).

필터. role 네임스페이스는 manifest/roles, project는 manifest/projects.yaml에서 해석해 합집합 src/pull.ts:L130-L239. rules는 namespace/ 접두가 있는 것만 knowledge 네임스페이스로 걸러지고 루트 rule은 항상 포함 src/pull.ts:L250-L262. skills는 (role/project 디렉터리) ∪ (구독 tag 일치) − excludedSkills src/pull.ts:L601-L639. role 미설정·project 매니페스트 없음이면 전량 동기화(null 컨텍스트) src/pull.ts:L150.

리소스대상 경로(툴별)근거
skills<baseDir>/<toolPaths[tool].skills>/<name> — 디렉터리 단위 flat 설치. 구체값은 teamai.yaml toolPaths(기본값은 미고정 types.ts)이며 문서상 ~/.claude/skills/, .opencode/skills/·~/.config/opencode/skills/, .qoder/skills/, .zcode/skills/ [project-stated]src/pull.ts:L335-L347, docs/usage-guide.md L273, L1350, L1358, L1362
rules<baseDir>/<toolPaths[tool].rules>/<name>.md(툴별 .mdc 확장자 변형 포함); 문서상 ~/.claude/rules/; OpenCode는 opencode.json instructions glob 추가src/pull.ts:L576-L599, src/pull.ts:L736-L740, usage-guide L274, L1352
agents<baseDir>/<toolPaths[tool].agents>/<name>.md; 문서상 ~/.claude/agents/, .zcode/agents/; built-in teamai-recall 에이전트도 동반 배포src/pull.ts:L713-L721, src/pull.ts:L1016-L1028, usage-guide L1343
docsdocsHandler.pullItem(핸들러 미고정 → 대상 경로 unknown); teamwiki/.teamai/team-repo/ 안에 머문다src/pull.ts:L661-L673, src/pull.ts:L883
env<dataHome>/env.sh(getDataHome; 사용자 스코프면 ~/.teamai/env.sh [inference])src/pull.ts:L645-L659
learnings사용자 스코프: getUserLearningsDir()로 미러; 프로젝트 스코프: repo 직접 사용. 검색 인덱스 <dataHome>/search-index.jsonsrc/pull.ts:L864-L910
culture / claudemd / recall 블록<baseDir>/<toolPaths[tool].claudemd>에 마커 섹션으로 주입(injectClaudeMdSection; 문서상 ~/.claude/CLAUDE.md, ~/.cursor/CLAUDE.md); recall 블록은 agents+claudemd 둘 다 있는 Tier-1 툴만src/pull.ts:L922-L986, src/pull.ts:L1201-L1236, usage-guide L1041-L1042
hooks<hookScope.baseDir>/<toolPaths[tool].settings> — 아래 섹션 표 참조src/pull.ts:L1623-L1647
mcpreconcileMcpForConfig(미고정 mcp-reconcile.js); 문서상 ~/.cursor/mcp.json, ~/.codebuddy/mcp.json, ~/.codex/config.toml, .qoder/settings.json, opencode.json [project-stated]src/pull.ts:L1654-L1680, usage-guide L729-L734
packagespull은 설치하지 않는다. SessionStart 핸들러가 pull 전후 packageManifestHash를 비교해 힌트만 stash하고, 실제 설치는 별도 teamai packages 명령src/hook-handlers.ts:L84-L106, src/index.ts L6, README L242
co-author 정책툴 설정에 attribution 트레일러 on/off를 쓰기 전용으로 반영(정책 철회 시 되돌리지 않음)src/pull.ts:L1536-L1541

삭제 의미론. (1) tombstone: 팀 repo가 tombstone으로 표시한 rules(.md/.mdc)·skills(디렉터리)·agents(.md)를 설치된 모든 툴에서 remove()한다. skills만 .git 등 VCS 메타데이터가 있으면 보존·경고하고, rules/agents 파일은 로컬 수정 여부를 검사하지 않고 삭제한다 src/pull.ts:L708-L759. (2) 비활성 role/project 네임스페이스 skill 및 desired 집합 밖의 skill: 팀 소스와 바이트 동일(dirContentEqual, CONTRIBUTORS 제외)할 때만 삭제, 아니면 보존·경고 src/pull.ts:L294-L363, src/pull.ts:L772-L798. (3) 구버전 네임스페이스 중첩 복사본 중 excludedSkillsSKILL.md 존재만 확인하고 안전 게이트 없이 삭제 src/pull.ts:L800-L815. (4) pullAllRules는 빈 집합에서도 호출되어 stale rule 파일을 정리한다(핸들러 본문 미고정) src/pull.ts:L588-L592. 개별 pullItem의 덮어쓰기/병합 규칙은 resources/*가 미고정이라 unknown.

push 흐름 (end-to-end)

autoDetectInit + read-only 검사sync-lock (경합 시 에러)팀 클론 reset --hard + git pullpre-push sync로컬 툴 디렉터리 스캔 (skills/rules/env/agents)open-PR 대조번호 선택 프롬프트네임스페이스 결정pushItem 복사 + 브랜치/커밋/푸시provider.createPullRequestcheckout default

브랜치·커밋. 브랜치명 = generateBranchName(localConfig.username)(utils/git.js 미고정 → 정확한 포맷 unknown), 커밋 메시지 = [teamai] Push N resource(s) from <username>, 스테이징 대상 = pushItem 경로 + 존재하는 sweeper 디렉터리 rules/, env/, .codebuddy-plugin/ + (편집된 경우) teamai.yaml src/push.ts:L188-L212. 이미 열린 PR이 있는 리소스는 그 브랜치를 force-push로 갱신한다(reuseBranch; 주석 "the force-push above") src/push.ts:L228-L232. test-present: push-pending-pr.test.ts L308-L460.

MR/PR 생성. getProvider(teamConfig.provider)가 반환한 provider의 createPullRequest({repo, source, target=default branch, title, description, reviewers: teamConfig.reviewers, cwd})를 호출한다. 실패해도 브랜치는 이미 원격에 있고, provider가 git인데 GitLab로 감지되면 provider: gitlab·GITLAB_URL·GITLAB_TOKEN 설정을 안내한다 src/push.ts:L86-L139. provider 구현(providers/*)은 미고정이라 gh/glab CLI인지 REST API인지는 unknown; GITLAB_TOKEN with api scope 문구는 API 토큰 사용을 시사한다 [inference].

무엇이 올라가는가. 스캔 대상은 ['skills','rules','env','agents']뿐이며 세션 트랜스크립트·usage 이벤트·learnings는 teamai push 경로에 없다 src/push.ts:L504-L513. 단 env 타입이 pushable이고 env/ 전체가 sweeper로 스테이징되므로 로컬 env 파일에 시크릿이 있으면 PR로 나갈 수 있다(env 핸들러 미고정 → 마스킹 여부 unknown). learnings는 /teamai-share-learnings 스킬과 pull의 flushPendingLearnings, votes는 Stop 훅에서 별도 push된다(아래).

확인 게이트. 대화형 실행은 번호 선택 프롬프트(기본 all)를 거치지만 --all 또는 --silent면 전량 자동 선택 src/push.ts:L738-L753. --dry-run은 표시 후 종료 src/push.ts:L732-L737. 안전장치: 팀 클론이 전용 git root가 아니면 중단(사용자 작업 트리 보호) src/push.ts:L436-L447; self 모드는 격리 worktree에서 실행 src/push.ts:L333-L388; 실패 시 팀 클론에 reset --hard + clean -fd src/push.ts:L258-L273. 리뷰·승인·머지 자체를 강제하는 코드는 push.ts에 없다 — reviewers를 PR 필드로 넘길 뿐이다.

# commands — not run (README L122, L241, L242 인용)
teamai push → create branch + MR → reviewer approves + merges
teamai push          # Push local resources to a branch and open a Merge Request
teamai packages [install] [target]

훅 주입과 런타임 핸들러

주입 엔진. 모든 툴은 단일 teamai hook-dispatch 명령으로 통일되어 있고(레거시 개별 서브커맨드는 마이그레이션 시 정리) src/hooks.ts:L24-L28, 포맷은 claude(Claude Code·CodeBuddy·WorkBuddy·Qoder 등 settings.json), cursor(hooks.json, camelCase 이벤트), codex(hooks.json), zcode(~/.zcode/cli/config.jsonhooks.events, hooks.enabled=true를 강제로 켠다) 4종 src/hooks.ts:L128-L139, src/hooks.ts:L545-L553. Hermes는 config.yaml, OpenClaw 계열(openclaw/qclaw/easyclaw/autoclaw)은 HOOK.md+handler.ts, OpenCode는 ~/.config/opencode/plugin/의 플러그인 파일(항상 HOME, 프로젝트 복사본은 삭제) src/hooks.ts:L13-L22, src/hooks.ts:L953-L981, src/hooks.ts:L1067-L1101. 설정 파일 경로 = <baseDir>/<toolPaths[tool].settings>이고 툴 루트 디렉터리가 이미 존재할 때만 쓴다 src/hooks.ts:L1102-L1123. 프로젝트 스코프(self 제외)의 훅도 HOME 설정 파일에 들어가며 팀 훅 명령은 $PWD 게이트로 감싼다 src/hooks.ts:L238-L256, src/pull.ts:L1381-L1386.

기존 사용자 훅 보존. reconcile은 "teamai 관리 엔트리"(description 접두 [teamai]/[teamai:hook:, 또는 명령에 teamai ... 마커, 또는 manifest에 기록된 명령)만 교체하고 나머지는 untouched로 보존한다 src/hooks.ts:L359-L419. 변경이 없으면 파일을 쓰지 않는다(idempotent). test-present: hooks.test.ts L194-L232(사용자 훅 보존), L130-L192(멱등), L235-L275(제거 시 타 훅 보존). 공개 Codex는 사용자가 /hooks에서 신뢰해야 실행될 수 있고 teamai는 [hooks.state]를 건드리지 않는다 src/hooks.ts:L141-L168.

이벤트툴 설정 파일(형식별)핸들러 → 런타임 동작근거
SessionStart / sessionStartclaude: <base>/.claude/settings.json(codebuddy·workbuddy·qoder 동형) · cursor: .cursor/hooks.json · codex: ~/.codex/hooks.json · zcode: ~/.zcode/cli/config.json · opencode: session.created 플러그인pull(background, 15s: seedProjectAgentRootpull({silent:true}) → package 힌트 stash), dashboard-report(로컬 이벤트 append), mr-hint(gitOnly), package-hint, local-agent-sync(HTTP report/sync)src/hook-handlers.ts:L452-L460, src/hook-handlers.ts:L84-L106
Stop / stop동일update(background, npm 레지스트리 조회), votes-sync(gitOnly, 트랜스크립트 파싱 → votes/<user>.yaml 팀 repo push), contribute-check(gitOnly, friction 힌트), dashboard-report(background), local-agent-sync(background)src/hook-handlers.ts:L462-L473
PostToolUse / postToolUse동일(matcher *, Skill, TodoWrite 3엔트리)dashboard-report, track(Skill 호출·Cursor의 SKILL.md Read를 usage.jsonl에 기록), todowrite-hint(recall 힌트, TEAMAI_RECALL_DISABLED=1로 차단), local-agent-syncsrc/hook-handlers.ts:L475-L479, src/hook-handlers.ts:L132-L170
UserPromptSubmit / beforeSubmitPrompt동일pending-hint(gitOnly, Stop stdout 미지원 툴용 stash 전달), package-pending-hint, track-slash(/skill 프롬프트 기록), dashboard-report, local-agent-syncsrc/hook-handlers.ts:L481-L486
PreToolUsebuilt-in 등록 없음. HTTP 소스의 서버 푸시 "agent hook" 화이트리스트에만 포함src/hooks.ts:L594-L596

Stop 훅이 읽는 것. contribute-check는 stdin의 session_id(없으면 pid+cwd 파생), cwd, transcript_pathcontributeCheckForSession()에 넘긴다; friction 점수 계산·"세션당 1회" 로직은 미고정 contribute-check.ts에 있어 이 증거 세트로는 검증 불가 src/hook-handlers.ts:L210-L232. votes-synctranscript_path 파일을 parseTranscriptForVotes로 읽어 recalledDocIds/referencedDocIds를 뽑고, 로컬 votes/<username>.yaml을 갱신한 뒤 syncVotesToTeam(git) 또는 self 모드의 commitAndPushReports팀 repo에 push한다; 실패는 조용히 삼킨다 src/hook-handlers.ts:L286-L331. recall 후 선언이 없으면 중국어 nudge 메시지를 모델에 되돌려 다음 턴을 강제한다(Cursor는 세션당 1회 캡) src/hook-handlers.ts:L332-L387. TEAMAI_ADOPTION_EVAL_LOG 설정 시 로컬 파일에 A/B 라인을 추가한다(opt-in) src/hook-handlers.ts:L354-L371.

옵트아웃. contribute 힌트: isContributeHintEnabled(localConfig, teamConfig)를 매 실행 시 평가(README의 sharing.contributeHint.enabled/contributeHintEnabled에 대응 [inference — 함수 본문 미고정]); 설정을 읽지 못하면 enabled로 폴백 src/hook-handlers.ts:L193-L208. recall/votes/todowrite: 환경변수 TEAMAI_RECALL_DISABLED=1 src/hook-handlers.ts:L289, src/hook-handlers.ts:L398. 툴 단위: enabledAgents/disabledAgents로 주입 제외 src/hooks.ts:L1203-L1219; 팀 단위 built-in 훅 disable/timeout 오버라이드는 hooks/hooks.yamlbuiltinOverride src/hooks.ts:L190-L193. SessionStart 자동 pull 자체를 끄는 전용 플래그는 이 파일들에 없다(훅 제거 또는 builtinOverride 경유만 [inference]). HTTP 소스면 gitOnly 핸들러가 제거되며, 설정 파싱 실패 시엔 전체 레지스트리가 유지된다(주석이 "Fail-open by design"이라 명시) src/hook-handlers.ts:L490-L518.

자동 동작의 실행 정책(fail-open/closed 판정)

문서 vs 코드 불일치

  1. "every AI session automatically pulls … no manual sync needed"(README L53) — 부분 지지. SessionStart 훅이 주입된 툴에서만 성립하며, 훅이 없는 툴(문서 자체가 JoyCode를 수동 pull 대상으로 명시, usage-guide L1377), 락 경합으로 스킵된 스코프 src/pull.ts:L1434-L1440, git pull 실패 src/pull.ts:L499-L502, 공개 Codex의 신뢰 게이트 src/hooks.ts:L141-L150는 조용히 동기화를 건너뛴다. 또한 README는 "pull"이 usage 통계·pending learnings·votes를 팀 repo로 push한다는 사실을 이 문장 근처에서 언급하지 않는다 src/pull.ts:L1542-L1592.
  2. "Stop hook scores it by friction … interrupted, denied a tool call, retried failing tools"(README L155) — 이 증거 세트로는 unknown. 핸들러는 transcript_path를 넘길 뿐이고 src/hook-handlers.ts:L223-L228 점수 함수는 미고정 파일에 있다. 항목별 신호 계산은 project-stated로만 분류.
  3. "Each session is prompted at most once"(README L165) — unknown(contributeCheckForSession 미고정). 반면 recall nudge는 Cursor만 세션당 1회 캡이고 다른 툴은 선언이 나올 때까지 매 Stop 반복될 수 있다고 코드 주석이 명시 src/hook-handlers.ts:L332-L352 — README의 "at most once"가 contribute 힌트에 한정된 진술임을 독자가 구분해야 한다.
  4. "Teams can switch the hint off with sharing.contributeHint.enabled: false"(README L165) — 부분 지지. 게이트 함수는 존재하나 설정 읽기 실패 시 켜짐으로 폴백한다 src/hook-handlers.ts:L193-L208. 키 이름 매핑은 미고정 types.tsisContributeHintEnabled에 있다.
  5. "push → create branch + MR → reviewer approves + merges"(README L122) — 부분 지지. 브랜치·PR 생성과 reviewers 전달은 코드에 있으나 src/push.ts:L109-L118, 승인·머지를 요구하거나 검증하는 코드는 없고 PR 생성 실패 시 브랜치만 남긴 채 수동 PR을 안내한다 src/push.ts:L120-L123. learnings(flushPendingLearnings)와 votes는 이 MR 경로를 거치지 않고 직접 push된다 src/pull.ts:L111-L117, src/hook-handlers.ts:L313-L330(README L165 "pushes a learning document directly to the team repo"와는 일치).
  6. "Packages … npm packages and Claude Code plugins"(README L142, L242) — pull 경로에서 설치 코드 없음 확인; 설치는 명시적 teamai packages 명령이며 SessionStart는 힌트만 낸다 src/hook-handlers.ts:L89-L103. README와 충돌하지 않으나 "자동 pull"에 패키지 설치가 포함된다고 오독될 여지가 있다.
05

아키텍처·실행 흐름

구성 요소 지도 (핀 트리 기준)

패키지는 단일 npm CLI(teamai)다. 소스 479개 .ts 파일 중 src/__tests__ 249개를 빼면 약 230개 모듈이며, 이번 정독은 그중 엔트리·핵심 3흐름·훅·설정·경계 모듈 13개다. 아래 지도의 "정독" 표시가 없는 계층은 트리 인벤토리(경로·크기)로만 안다.

계층모듈 (핀 트리)역할이번 범위
엔트리src/index.ts (1,122줄) · src/bootstrap.ts · src/config.tscommander 프로그램, 76개 .command( 등록, preAction 자동 마이그레이션, self 모드 자동 부트스트랩, 설정 파티션(~/.teamai/projects/<slug>/)정독
핵심 흐름src/init.ts · src/pull.ts · src/push.ts팀 repo 연결·멤버 등록·훅 주입 / 팀 repo → 툴 디렉터리 미러링 + usage·learnings 역송신 / 로컬 리소스 → 브랜치·PR정독
src/hooks.ts · src/hook-handlers.ts · src/hook-dispatch*.ts · src/builtin-hooks.ts툴별 settings 파일에 teamai hook-dispatch 주입(SessionStart·Stop·PostToolUse·UserPromptSubmit), 런타임 핸들러 레지스트리hooks.ts·hook-handlers.ts 정독 / dispatch-cli·builtin 미정독
툴 어댑터src/local-agent.ts (3,429줄) · src/known-agents.ts · src/types.ts (toolPaths)Claude Code·Codex·Cursor·CodeBuddy·OpenCode·OpenClaw·Hermes·Qoder·ZCode 등 툴별 경로·형식미정독 (경로만)
Git 제공자src/providers/ 29파일 (github/gitlab/gitcode/cnb/tgit/git)인증·clone URL·PR 생성·레포 생성미정독 (docs/providers.md만 정독)
지식 계층src/recall.ts · src/wiki-engine/ 31파일 · src/codebase*.ts · src/import*.ts · src/deep-enrich.tsBM25+그래프 검색, tree-sitter AST 추출, teamwiki 생성, AI CLI로 문서 생성미정독 (README 주장은 11절에서 unknown 처리)
측정·리포트src/usage-tracker.ts · src/session-collector.ts · src/dashboard*.ts · src/digest.ts · src/votes.ts · src/utils/reports-branch.ts스킬 사용 이벤트, 세션 요약, votes, 팀 stats/·teamai-reports 브랜치usage-tracker·session-collector 정독 / 나머지 미정독
경계src/api-key.ts · src/machine-id.ts · src/utils/ai-client.tsAPI 키 파일(0600 평문), 기기 식별자, 외부 AI CLI 호출정독

실제 엔트리포인트

npm bin teamaidist/index.js (= src/index.ts)program.hook('preAction') → maybeMigrate.command().action → 지연 importdetectProjectConfig (self 모드면 bootstrapSelfRepo)

빌드 산출물은 tsup ESM 번들 하나이며 package.jsonbin이 유일한 진입이다 package.json:L6-L8. 명령 액션은 실행 시점에 await import('./x.js')로 모듈을 로드하므로 콜드 스타트에 전체 모듈이 올라오지 않는다 src/index.ts:L69-L73. 훅이 호출하는 hidden 명령 8개(track·contribute-check·dashboard-report 등)도 같은 프로그램에 등록돼 있다.

end-to-end 흐름 1 — 세션 시작 (SessionStart 훅 → 자동 pull → 역송신)

에이전트 툴 세션 시작settings 훅: teamai hook-dispatch7초 하드 타이머 · 항상 exit 0background pull({silent:true})git pull 팀 repoflushPendingLearnings (add/commit/push)skills/rules/docs/agents → 툴 디렉터리tombstone 삭제 · hooks/MCP reconcileusage.jsonl → 팀 stats 보고 후 truncate

디스패처는 IDE를 막지 않기 위해 7초 뒤 무조건 process.exit(0)한다 src/index.ts:L737-L756; 핸들러는 pull을 silent로 백그라운드 실행하고 실패를 삼킨다 src/hook-handlers.ts:L452-L456. pull 본문은 git pull 직후 미전송 learnings를 push하고 src/pull.ts:L102-L117, 말미에 ~/.teamai/usage.jsonl을 팀 repo로 보고한 뒤 비운다 src/pull.ts:L1542-L1592. 즉 "pull"은 양방향이다.

end-to-end 흐름 2 — 세션 종료 (Stop 훅)

세션 Stophook-dispatch (stdin: session_id·cwd·transcript_path)contribute-check (friction 판정, 미정독 모듈)votes-sync: transcript 파싱 → votes/<user>.yaml commit·pushupdate 체크 (npm 레지스트리, detached)recall 미선언 시 모델에 nudge 반환

Stop 핸들러 레지스트리는 src/hook-handlers.ts:L450-L488에 있다. votes-sync는 TEAMAI_RECALL_DISABLED=1만 확인하고 push 실패를 삼킨다 src/hook-handlers.ts:L286-L331. friction 점수 함수 자체는 contribute-check.ts(미정독)에 있어 README의 "신호 3종·세션당 1회"는 이 문서에서 검증되지 않았다.

end-to-end 흐름 3 — 공유 (push → PR)

teamai push팀 클론 reset --hard + pull로컬 툴 디렉터리에서 skills/rules/env/agents 스캔번호 선택 프롬프트 (--all/--silent면 생략)브랜치 generateBranchName(username) · 커밋provider.createPullRequest(reviewers)실패 시 브랜치만 남기고 수동 안내

스캔 대상은 4종뿐이며 env/는 디렉터리째 스테이징된다 src/push.ts:L504-L513. 승인·머지를 요구하는 코드는 없고, learnings(pull)·votes(Stop)는 PR을 거치지 않고 직접 push된다 src/push.ts:L86-L139.

문서 vs 관측 차이 (요약)

  • README "push → MR → pull"의 세 화살표 밖에 init의 팀 repo push·원격 레포 생성(기본 Yes), pull 안의 learnings/usage push, Stop의 votes push가 있다 (4절·9절).
  • README "모든 세션이 자동 pull" — 훅이 주입된 툴에서만, 락 경합·git 실패·Codex 신뢰 게이트는 조용히 건너뛴다 src/pull.ts:L1434-L1440 src/hooks.ts:L141-L150.
  • README "init: OAuth login" — 제공자 의존; 일반 git 제공자는 Git identity 해석만 한다 src/init.ts:L1100-L1111.
06

설치와 첫 성공

이 절의 명령은 전부 저장소 저자가 쓴 것을 인용한 것이며 이 문서 작성 과정에서 하나도 실행하지 않았다 (commands — not run). 성공 신호와 정리 절차도 문서·코드에서 읽은 것이지 관측이 아니다.

선행 조건

  • Node.js — package.jsonengines 선언이 없다 package.json; CI 매트릭스는 Node 20/22 × ubuntu/macos ci.yml:L19-L27 (Windows 러너 없음). AGENTS.md는 "Node 20+" AGENTS.md:L5.
  • git 호스트 저장소(GitHub·GitLab·GitCode·CNB·TGit·사설 git) + 팀원 쓰기 권한 README.md:L36. 제공자 CLI(gh·gf·cnb)나 토큰이 인증에 쓰인다 docs/providers.md.
  • 대상 AI 툴이 HOME/프로젝트에 이미 설치돼 있어야 훅·리소스가 쓰인다 — 툴 루트가 없으면 건너뛴다 src/hooks.ts:L1102-L1123.

저자 명령 인용 (commands — not run)

# commands — not run (README.md L30-L32, L45-L50; 이 문서는 실행하지 않았다)
npm install -g teamai-cli

cd /path/to/my-project
teamai init https://github.com/yourorg/yourrepo            # project scope (기본)
teamai init https://github.com/yourorg/yourrepo --scope user  # user scope (~/)

이 문서의 판단(3절)에 따르면 첫 실행은 전역 옵션 --dry-run과 함께 하는 편이 안전하다 — commander 전역 옵션으로 정의돼 있고 init의 팀 repo push를 막는다 src/index.ts:L13-L23 src/init.ts:L1284-L1305. 안정 버전 고정([email protected])은 이 문서의 권고이지 저자 명령이 아니다.

필요한 환경 · 서비스

항목근거
설정 파일~/.teamai/config.yaml(user) · ~/.teamai/projects/<slug>/config.yaml(project 파티션)config.ts:L71-L75 config.ts:L139-L169
팀 클론<teamaiHome>/team-repoinit.ts:L1118-L1226
API 키(HTTP 모드)TEAMAI_API_TOKENTEAMAI_API_KEY~/.teamai/apikey(평문, 0600)api-key.ts:L29-L53
옵트아웃 스위치TEAMAI_CONTRIBUTE_HINT_DISABLED=1 · TEAMAI_RECALL_DISABLED=1 · sharing.contributeHint.enabled · TEAMAI_SKIP_AST=1hook-handlers.ts:L193-L208 hook-handlers.ts:L289

기대 성공 신호 (문서·코드 기준)

  • init 후 팀 repo에 members/<username>.yaml 커밋이 생기고 init.ts:L1276-L1293, 대상 툴 settings에 teamai hook-dispatch 항목이 4이벤트로 들어간다 hook-handlers.ts:L450-L488.
  • teamai status가 로컬 vs 팀 repo 차이와 리소스 수를 보고한다 (README L243, project-stated). teamai doctor는 설정 진단 (README L264).

제거 · 정리

# commands — not run (README.md L265)
teamai uninstall      # 모든 teamai 리소스와 훅 제거 (사용자 생성물 보존은 project-stated, src/uninstall.ts 956줄 미정독)

팀 repo에 이미 push된 members/·stats/·votes/·learnings와 teamai-reports 브랜치는 uninstall이 지우지 않는다고 봐야 한다 [추정 — uninstall.ts 미정독].

비실행 영수증

이 절을 포함해 문서 전체에서 설치·빌드·테스트·실행은 0건이다. 13절의 정적 전용 영수증 참조.

07

권장 읽기 순서

사용자

  1. README.md:L26-L55 — 설치·init·자동 pull 계약 (5분)
  2. docs/usage-guide.md:L359-L427 — 멤버 온보딩과 Auto-sync, 훅 미지원 툴 예외 (8분)
  3. docs/usage-guide.md:L498-L546 — 스킬 제외와 push 흐름 (6분)
  4. docs/usage-guide.md:L766-L835 — 공유 힌트 끄기, recall 켜기·끄기 (8분)
  5. docs/usage-guide.md:L1533-L1547 — uninstall과 --dry-run (3분)

운영자

  1. README.md:L100-L145 — 배포 제어 4종과 공유 리소스 표 (5분)
  2. docs/usage-guide.md:L98-L285 — 관리자 init, 다중 프로젝트, 스코프 선택 (15분)
  3. docs/usage-guide.md:L700-L753 — MCP 배포와 시크릿이 디스크에 남는 경고 (6분)
  4. docs/usage-guide.md:L1278-L1328 — 내장 훅 표, Codex trust gate, 팀 훅 autoApply (8분)
  5. docs/usage-guide.md:L1398-L1439 — 자동 업데이트 2단 설정, CI extract-mr (6분)
  6. docs/designs/data-directory-layout.md:L25-L48 — 두 앵커 모델과 ~/.teamai/projects/<slug>/ (5분)

기여자

  1. AGENTS.md:L1-L25 — 저장소 규칙 전문; CLAUDE.md와 동일 내용이라는 진술 (3분)
  2. .github/CONTRIBUTING.md:L1-L80 — 빌드·테스트 명령; 브랜치명·providers 목록 노후 주의 (5분)
  3. src/index.ts:L1-L120 — 전역 옵션, 자동 마이그레이션 preAction, init/push/pull 등록 (10분)
  4. src/index.ts:L717-L757 — hook-dispatch 진입점과 타임아웃 설계 주석 (5분)
  5. CHANGELOG.md:L1-L100 — 최근 세 릴리즈의 변경 밀도와 파티션 리팩터링 (10분)
  6. docs/designs/data-directory-layout.md:L1-L283 — P0-P3 설계 노트 전문 (20분)

보안 리뷰어

  1. docs/usage-guide.md:L1278-L1296 — 어떤 이벤트에 무엇이 걸리는지; Codex는 자동 trust하지 않음 (5분)
  2. src/index.ts:L717-L757 — 훅 프로세스가 process.exit(0)으로 오류를 삼키는 설계와 분리 자식 (5분)
  3. docs/usage-guide.md:L429-L469 — packages: pull은 안내만, 서드파티 코드 자동 실행 없음이라는 진술 (6분)
  4. docs/usage-guide.md:L749-L753 — MCP 시크릿 ${VAR} 해석 결과가 프로젝트 설정 파일에 평문으로 남음 (3분)
  5. docs/usage-guide.md:L1232-L1273 — 수집 항목(정정 키워드 감지, 토큰·비용, requests.jsonl 90일)과 session save --push의 직접 커밋 (8분)
  6. docs/usage-guide.md:L1190--deep-enrich가 로컬 AI CLI를 셸 호출(코드 유출 경로) (2분)
08

건강도·릴리즈

유지보수 건강도 — 캡처 2026-09-11 04:50–05:00Z, 핀 커밋 34e1cfb

아래 수치는 전부 GitHub REST 응답 캡처(페이지당 10~30건 표본)에서 계산한 값이다. 표본 밖의 전수(全數) 주장은 하지 않으며, 각 숫자에 표본 크기와 시간 창을 붙였다. CI 항목은 역사적 메타데이터이지 이 문서가 로컬에서 실행해 얻은 결과가 아니다.

HEAD 신선도push 후 약 1.2시간 (2026-09-11T03:40Z)
릴리즈 케이던스10건 / 2.86일 ≈ 3.5건/일 (베타 8 · 안정 2)
핀 커밋 CIsuccess (run 34556837353, check-run 6/6)
이슈 첫 응답 중앙값11.8시간 (n=6, 0.19–955시간)
PR 머지 비율24/30 = 80% (닫힌 PR 표본), 머지 중앙값 8.9시간
기여 집중도jeff-r2026 549/702 = 78.2% (30명 응답)

HEAD 신선도

  • repository.pushed_at = 2026-09-11T03:40:06Z. 캡처 시각(약 04:55Z) 기준 약 1.2시간(0.05일) 전. 핀 커밋의 committer date는 2026-09-11T03:01:12Z(캡처 약 1.9시간 전)이며, pushed_at이 핀 커밋보다 39분 뒤인 이유는 같은 시각에 릴리즈 봇이 v0.24.0-beta.6 태그를 push했기 때문으로 읽힌다(releases.json published_at 03:40:40Z와 일치).
  • 핀 커밋 자체: fix(deep-enrich): retry missing AI docs after temporary failures (#491), 작성자 jimpablo, 단일 부모(squash 머지 산출물).
  • 최근 커밋 30건 표본(창 2026-09-09T13:12Z → 2026-09-11T03:01Z, 약 1.6일): 작성자별 jeff-r2026 14 · jimpablo 3 · STiFLeR7 3 · FenjuFu 2 · ousamabenyounes 2 · nateEc 2 · linjinglan 1 · Yi-111-a 1 · yakimoto 1 · Beverly621 1. 이 중 머지 커밋 12건은 전부 jeff-r2026가 만든 것이라, jeff-r2026의 14건 중 자기 코드 커밋은 2건뿐이다. 즉 코드 작성은 10명에 분산되지만 main 반영(머지) 권한은 표본상 1인이다.
  • 30건 중 committer가 GitHub(웹 UI/PR 머지)인 커밋 16건 — 나머지 14건은 로컬 커밋이 PR을 거쳐 rebase/squash된 흔적.

릴리즈 vs 태그

releases.json(10건)과 tags.json(10건)은 별개 시계열로 봤다. 표본에서는 두 목록의 이름이 완전히 일치한다(태그 10개 = 릴리즈 10개, 태그만 있고 릴리즈 없는 항목 없음).

항목표본·창
릴리즈 수10 (prerelease 8, stable 2, draft 0)per_page=10, 2026-09-08T06:58Z → 2026-09-11T03:40Z
케이던스10건 / 2.86일 ≈ 3.5건/일표본 첫 published_at → 마지막 published_at
최신 stablev0.23.1 (2026-09-09T06:37Z)직전 stable v0.23.0 2026-09-08T11:01Z
최신 anyv0.24.0-beta.6 (2026-09-11T03:40Z)beta.1(09-09T04:02Z)부터 6개 베타가 약 2일 안에 나옴
발행 주체10건 전부 github-actions[bot]사람이 손으로 만든 릴리즈는 표본에 0
CHANGELOG 상단0.23.0(09-08) · 0.22.0(09-02) · 0.21.0(08-27) · 0.20.0(08-20) · 0.19.0(08-06)핀 블롭 상위 120줄; minor 버전 간격 약 5~14일. 0.23.1 항목은 상위 120줄에 없음
  • 버전 충돌 기록: 핀 커밋의 package.json version은 0.22.0인데, 최신 stable 릴리즈/태그는 v0.23.1, 최신 태그는 v0.24.0-beta.6, CHANGELOG 최상단은 0.23.0이다. 릴리즈 워크플로가 매니페스트 버전을 소스에 되돌려 쓰지 않는 방식이거나 매니페스트가 stale한 것 중 하나인데, 캡처만으로는 어느 쪽인지 판정 불가 — [추정].
  • 해석: 하루 3건 이상의 베타 태그는 "활발함"의 신호인 동시에 "베타 채널은 안정 채널이 아님"의 신호다. 도입 시 stable 태그(v0.23.1) 또는 명시 SHA로 고정해야 하며, npm latest/베타 태그 추종은 하루 단위로 동작이 바뀔 수 있다.

핀 커밋의 CI (역사적 메타데이터)

  • 워크플로(workflows.json, 2건 반환): CI(.github/workflows/ci.yml, active) · Release(.github/workflows/release.yml, active).
  • 최근 실행 20건 표본(main, 창 2026-09-09T06:29Z → 2026-09-11T03:01Z; 저장소 누적 total_count 363): 전부 워크플로 CI, 이벤트 push, status completed. 결론 success 16 · cancelled 4(failure 0). cancelled 4건은 연속 push 시 concurrency 취소로 읽히나 캡처엔 사유 필드가 없다 — [추정]. Release 워크플로 실행은 이 20건 표본에 포함되지 않았다(브랜치 필터 main/push 표본이라 태그 트리거 실행이 잘렸을 가능성).
  • 핀 SHA 34e1cfb의 실행: run id 34556837353, name CI, event push, conclusion success, created 2026-09-11T03:01:15Z.
  • 핀 SHA의 check-runs(check-runs-pinned.json, total 6): Lint & Test (Node 20 on ubuntu-latest) · Lint & Test (Node 22 on ubuntu-latest) · Lint & Test (Node 20 on macos-latest) · Lint & Test (Node 22 on macos-latest) · Build · E2E (GitHub provider, full surface)6/6 completed·success, 마지막 완료 03:05:15Z.
  • 한계: 위는 GitHub가 기록한 결과의 메타데이터다. 이 문서는 테스트를 로컬에서 재실행하지 않았고, 매트릭스에 Windows 러너가 없다는 점(캡처된 6개 check 이름 기준)도 도입 환경에 따라 공백이다.

이슈·PR 응답 표본

지표표본·규칙
열린 이슈 수(API)open_issues_count = 21GitHub 정의상 PR 포함 수치. 열린 표본 21행 = 순수 이슈 15 + PR 6으로 정확히 일치
열린 순수 이슈15행 (댓글 0개 = 11/15)issues-open.json, sort=updated, 창 2026-09-01T14:21Z → 2026-09-11T03:49Z. 작성자 jeff-r2026 12/15(메인테이너 자기 기록형 이슈), 외부 3
닫힌 순수 이슈13행 (PR행 17 제외)issues-closed.json 30행, closed_at 창 2026-09-10T02:32Z → 2026-09-11T03:29Z; state_reason completed 12 · not_planned 1
표본 내 닫힘 비율13 / (15+13) = 46%두 표본의 시간 창이 다르므로(열린 표본은 10일, 닫힌 표본은 약 1일) 비율 자체보다 "하루에 13건이 닫혔다"는 처리량이 더 유의미
닫힌 이슈 소요일중앙값 0.73일 (0.04–112일)n=13, created_at → closed_at
첫 비저자·비봇 응답중앙값 11.8시간, 범위 0.19–955시간n=6(#424 #492 #360 #17 #459 #471, 캡처 측이 고른 유계 표본). 규칙: 댓글 중 user.login ≠ 이슈 작성자이고 user.type ≠ Bot인 첫 댓글까지의 시간. 6건 모두 적격 응답 존재 — "댓글 0" 0건, "응답 없음" 0건, 봇 댓글 0건
  • 응답 표본 세부(시간): #424 0.19h(jeff-r2026) · #459 2.03h(jeff-r2026) · #471 8.62h(jeff-r2026) · #492 15.0h(jeff-r2026) · #360 262.6h ≈ 10.9일(opsnull) · #17 955.3h ≈ 39.8일(jeff-r2026). 응답자 6건 중 5건이 jeff-r2026 — 응답 채널도 사실상 1인. 최근 이슈(9월)는 반나절 내, 오래된 이슈(5월·8월)는 주 단위였다.
  • PR: 열린 6건(draft 0, 가장 오래된 것 2026-09-09T14:39Z) · 닫힌 30건 표본(closed_at 창 2026-09-09T03:10Z → 2026-09-11T03:01Z) 중 머지 24건 = 80%, 미머지 닫힘 6건. 머지 소요(created_at → merged_at) 중앙값 8.88시간, 범위 0.4–20.4시간(n=24). 닫힌 PR 작성자 상위: jeff-r2026 9 · jimpablo 5 · STiFLeR7 3 · nateEc 3. list 엔드포인트라 merged_by는 null이며 누가 머지했는지는 커밋 표본(머지 커밋 12/12 jeff-r2026)으로만 추정한다.
  • 해석: 외부 PR이 하루 안에 머지되는 속도는 빠르지만, 머지·응답·이슈 작성이 모두 한 계정으로 수렴한다. 그 계정의 부재 시 처리량이 어떻게 되는지는 표본으로 알 수 없다.

기여자·커뮤니티

  • contributors.json 30명 반환(per_page=30, 더 있을 수 있음), 응답 내 contributions 합계 702. 상위 5: jeff-r2026 549(78.2%) · m0Nst3r873 89(12.7%) · Eyre921 6(0.9%) · laolaoPlayer 6(0.9%) · Iapa 5(0.7%). 상위 2인이 90.9%. 봇 계정 0.
  • 주의: contributions는 기본 브랜치 커밋 수이며, 이 집중도는 버스 팩터가 아니다. squash 머지에서는 머지한 사람이 아니라 PR 작성자가 author로 남으므로 이 수치는 "누가 코드를 썼나"에 가깝고, 조직(Tencent) 차원의 접근 권한·백업 메인테이너 존재 여부는 캡처에 없다.
  • 커뮤니티 프로필 health_percentage = 62. 파일 존재(API 기준): README true · LICENSE true · CONTRIBUTING true · PULL_REQUEST_TEMPLATE true · CODE_OF_CONDUCT false · ISSUE_TEMPLATE false. 라이선스는 spdx_id NOASSERTION(GitHub가 표준 SPDX로 인식하지 못한 텍스트) — 라이선스 절에서 별도 판정.
  • 문서 vs API 불일치: 핀 트리에는 .github/ISSUE_TEMPLATE/bug_report.mdfeature_request.md가 있는데 community-profile API는 issue_template=false로 응답한다. 프로필 캐시 지연, 템플릿 frontmatter 미인식, 또는 API가 요구하는 형식 차이 중 어느 것인지 판정 불가 — verdict unknown으로 기록.

관심 신호(참고만)

  • stars 3,919 · forks 252 · subscribers(watch) 11 — 캡처 시점 단일 스냅샷. 관심도이지 품질·유지보수 지표가 아니며, 특히 watch 11은 star 대비 매우 낮아 "구경은 많고 추적은 적은" 초기 확산 단계 패턴으로 읽힌다 — [추정].
  • languages.json(bytes): TypeScript 4,748,102 · Python 16,297 · JavaScript 3,438. 사실상 TypeScript 단일 언어(99.6%).
09

보안·개인정보·공급망

자격증명 경계

정적 분석 대상은 pinned commit 34e1cfb의 redacted 사본이다. 아래 모든 진술은 파일:행을 동반하며, 실행·설치·테스트는 하지 않았다 (런타임 동작은 관찰하지 않음).

식별자와 개인정보

기기 밖으로 나가는 것 (기본값 표)

훅 레지스트리 src/hook-handlers.ts:L450-L488는 SessionStart/Stop/PostToolUse/UserPromptSubmit 전 이벤트에 핸들러를 등록하며, 등록 자체에는 사용자 토글이 없다. 훅은 teamai init이 HOME의 도구 settings에 주입한다 src/hooks.ts:L822, src/hooks.ts:L988-L1009. self 모드 리포를 clone만 해도 다음 AI 세션에서 자동 init(훅 주입 + reports 브랜치 멤버 등록)된다고 문서화 docs/usage-guide.md:L318. 판정: fail-open = 비활성화하지 않으면 발생, fail-closed = 명시 활성화 필요.

데이터 흐름기본목적지opt-out 스위치근거
스킬 사용 이벤트 (Skill 툴콜, /slash 프롬프트 첫 단어) → JSONLon (fail-open)로컬 ~/.teamai/usage.jsonl, known-skills.json없음 (레지스트리에 토글 없음)src/usage-tracker.ts:L156-L165, src/hook-handlers.ts:L477-L484
usage.jsonl 자동 리포트 → 팀 리포 stats/ (pull 때, SessionStart 백그라운드 pull 포함)on (fail-open; http kind·dryRun만 제외)팀 git 리포 또는 teamai-reports 브랜치 (원격 push)코드상 스위치 미확인 → unknownsrc/pull.ts:L1542-L1591, src/hook-handlers.ts:L456
대시보드 이벤트 (툴 시퀀스·프롬프트 턴·개입·토큰) → 로컬 events.jsonl; 집계는 stats/<user>.yaml로 팀 공유on (fail-open; 4개 이벤트 전부 등록)로컬 ~/.teamai/dashboard/; 집계값은 팀 리포 (project-stated)없음 ("dashboard reporting keep running")src/hook-handlers.ts:L117-L130, docs/usage-guide.md:L1236-L1257, docs/usage-guide.md:L795
Stop 훅 contribute 힌트 (transcript 읽어 friction 판정, 모델 컨텍스트에 리마인더 주입)on (fail-open; config 읽기 실패 시에도 enabled)로컬(모델 컨텍스트). 실제 기여는 /teamai-share-learnings 실행 시 팀 리포 PRsharing.contributeHint.enabled=false / contributeHintEnabled / TEAMAI_CONTRIBUTE_HINT_DISABLED=1 (git 모드만 등록)src/hook-handlers.ts:L193-L231, docs/usage-guide.md:L797-L801
votes-sync (transcript에서 recall doc-id 파싱 → votes/<user>.yaml 커밋·push)on at handler (fail-open; env 킬스위치만 검사)팀 리포 / teamai-reports 브랜치TEAMAI_RECALL_DISABLED=1; recall 팀 기본은 false이므로 실효 데이터는 recall 활성 시에만 [추정]src/hook-handlers.ts:L286-L330, docs/usage-guide.md:L825-L827
Stop 훅 npm 레지스트리 업데이트 확인 (detached)on (fail-open)npm registry (HTTP)미확인 (update.ts 사본 없음; CI config에 updatePolicy: auto 필드 존재)src/hook-handlers.ts:L465-L469, .github/workflows/ci.yml:L136
local-agent HTTP report/sync (HTTP 팀 모드: 세션 시작 시 설치 스킬 상태 보고, 서버 명령 pull)fail-closed 진입(init --http 필요) → 이후 모든 이벤트에서 자동설정한 HTTP 엔드포인트, Bearer API 키없음 (HTTP 모드 해제 외)src/hook-handlers.ts:L435-L441, src/hook-handlers.ts:L460-L486, docs/usage-guide.md:L389
teamai session save --push (세션 요약: 카운트+툴명+cwd; 첫 프롬프트는 --include-prompt)off (fail-closed; 로컬 저장은 항상)팀 리포 sessions/<user>/ 직접 커밋(no PR)플래그 미지정src/index.ts:L671-L676, src/session-collector.ts:L142-L165
AI CLI 호출 — 프롬프트(코드베이스 문서 생성·enrich 등 소스 코드 포함)를 argv로 전달off (fail-closed; 명시 명령 시)가장 먼저 발견된 외부 CLI: claude/claude-internal/tclaude/codex/codex-internal/tcodex/codebuddy/workbuddy/openclaw → 그 CLI 뒤의 LLM 벤더 [추정]없음 (우선순위 고정, 선택 옵션 미확인)src/utils/ai-client.ts:L7-L9, src/utils/ai-client.ts:L22-L28, src/utils/ai-client.ts:L198-L203, src/utils/ai-client.ts:L247
A/B 측정 로그 (TEAMAI_ADOPTION_EVAL_LOG)off (fail-closed)로컬 지정 파일env 미설정src/hook-handlers.ts:L354-L371

AI CLI 호출에서 프롬프트가 -p <prompt>/exec <prompt> 명령행 인자로 전달되므로 src/utils/ai-client.ts:L198-L203 동일 호스트의 다른 프로세스가 프로세스 목록으로 프롬프트(코드 조각)를 볼 수 있다 [추정]. 프롬프트 앞 60~80자는 debug 로그에도 남는다 src/utils/ai-client.ts:L246, src/utils/ai-client.ts:L256. 별도 HTTP 텔레메트리 엔드포인트(벤더 수집 서버)로의 발신은 읽은 사본 범위에서 발견되지 않았다; 모든 팀 공유는 git push 또는 사용자가 설정한 HTTP 팀 엔드포인트다 (static-support, 사본 범위 한정).

공급망

  • 런타임 의존성 15개 package.json:L48-L64: 대부분 caret 범위, tree-sitter-wasms 0.1.13·web-tree-sitter 0.25.10만 정확 고정 package.json:L60-L61. simple-git(git 서브프로세스), cross-spawn(AI CLI spawn) 포함. overrides: js-yaml ^3.15.1은 구 major 고정 package.json:L65-L67 (이유 미기재). engines 필드 없음; CI 매트릭스는 Node 20/22 .github/workflows/ci.yml:L22-L24. 배포 파일은 dist/**/*.js, skills, agents, README, CHANGELOG, LICENSE package.json:L9-L16.
  • WASM 파서: README는 "순수 JS 의존성, 네이티브 툴체인 불필요, 로드 실패 시 휴리스틱 폴백, TEAMAI_SKIP_AST=1" README.md:L210; pinned tree에 .wasm 파일 없음(패키지에서 로드; external-confirmed tree). WASM 바이너리 출처/무결성 검증은 unknown.
  • GitHub SBOM(SPDX 2.3, Dependency Graph 생성): 455 패키지, devDependency(opencode-ai 1.18.23과 플랫폼 바이너리, vitest, standard-version) 포함 (external-confirmed). licenseConcluded 집합에 GPL/LGPL/MPL 없음, CC-BY-3.0·빈값 항목 존재.
  • CI: npm ci --ignore-scripts를 모든 job에서 사용 .github/workflows/ci.yml:L36-L37, .github/workflows/release.yml:L29-L30. Actions는 태그 고정(actions/checkout@v4, setup-node@v4, upload-artifact@v4, softprops/action-gh-release@v2) — SHA 고정 아님 .github/workflows/ci.yml:L28-L31, .github/workflows/release.yml:L85. ci.yml에 top-level permissions: 없음 (토큰 권한은 리포 기본값 → unknown).
  • 릴리즈: v*.*.* 태그 push로 트리거 .github/workflows/release.yml:L3-L6, id-token: write + npm@^11.5.1 "trusted publishing" + npm publish에 토큰 시크릿 없음 .github/workflows/release.yml:L12-L14, .github/workflows/release.yml:L26-L27, .github/workflows/release.yml:L81-L82 → OIDC 기반 publish이며 provenance는 자동 첨부될 것으로 [추정] (--provenance 플래그는 명시되지 않음). 버전-태그 일치 검사·중복 publish 차단·prerelease dist-tag 분리 존재 .github/workflows/release.yml:L32-L79. 태그 push 권한자 = 퍼블리셔; 태그/브랜치 보호는 401로 unknown.
  • pinned tree(579 엔트리)에 없는 것: SECURITY.md, CODEOWNERS, NOTICE, .github/dependabot.yml, CodeQL 워크플로 (external-confirmed tree). 있는 것: .github/CONTRIBUTING.md, ISSUE_TEMPLATE/bug_report.md·feature_request.md, PULL_REQUEST_TEMPLATE.md, workflows/ci.yml·release.yml, 루트 .coding-ci.yaml(Tencent CODING CI 추정, 내용 미확보). 워크플로 2개 모두 active (workflows.json). GitHub community profile은 health 62%, code_of_conduct false, issue_template false로 보고 — tree에는 템플릿 파일이 있어 Tensions(탐지 규칙 차이 [추정]).
  • pinned commit은 GitHub 서명 검증 verified: true (external-confirmed, commit-pinned.json). 공개 advisory 0건([])은 "취약점 없음"이 아니라 "리포 advisory DB에 게시된 것 없음"이다.

미확인(unknown) 항목

  1. Branch protection, Code scanning, Dependabot alerts, Secret scanning — 모두 HTTP 401(미인증) → unknown, 0이 아님. repository.jsonsecurity_and_analysis: null도 동일.
  2. local-agent HTTP 페이로드의 정확한 필드(원시 machine_id 포함 여부, hostname, 설치 스킬 목록) — src/local-agent.ts 사본 없음.
  3. redactWithEnv가 마스킹하는 패턴 목록과 미마스킹 범위 — src/utils/redact.ts 사본 없음.
  4. usage.jsonl 자동 리포트(reportUsageToTeam)의 팀측 파일 스키마와 opt-out 존재 여부 — src/team-push.ts 사본 없음.
  5. Stop 훅 npm 업데이트 확인의 비활성 경로(updatePolicy 의미) — src/update.ts 사본 없음.
  6. transcript-parser.ts가 전사본에서 추출하는 필드의 전체 목록 (문서는 "카운트만"이라 진술).
  7. .coding-ci.yaml 내용(내부 CI가 무엇을 실행·발행하는지), .gitignore 내용(~/.teamai/apikey가 "project-scope .gitignore로 커버"된다는 주석의 실제 대상).
  8. npm 패키지에 실제 provenance attestation이 첨부되는지 (레지스트리 조회 미수행).
  9. GitHub provider clone URL의 토큰이 .git/config에 남는지 (providers.md L97은 URL 삽입을 기술; 코드 미확인).
  10. assets/*.svg 및 skills/·agents/ 배포 콘텐츠의 별도 라이선스/상표 정책.
10

라이선스·채택 조건

라이선스: 탐지값 vs pinned 텍스트

소스종류
pinned LICENSE 본문Tencent 헤더(L1-5: "Tencent is pleased to support…", "Copyright (C) 2026 Tencent", "licensed under MIT… does not impose any additional restrictions") + "Terms of the MIT License:" 이하 표준 MIT 허가·고지·면책 조항(L9-13) LICENSE:L1-L13static-support
package.json"license": "MIT" package.json:L47project-stated
README 배지"License: MIT" → LICENSE 링크 README.md:L12project-stated
GitHub 라이선스 탐지 (license.json, repository.json)key: "other", spdx_id: "NOASSERTION"external-confirmed

결론(분류): 실질 조건은 MIT와 동일한 permissive 라이선스이며, 헤더가 "MIT 외 추가 제한을 두지 않는다"고 명시한다 LICENSE:L5. 탐지 결과 NOASSERTION과의 충돌은 Tensions로 기록한다: GitHub의 licensee는 본문이 표준 MIT 템플릿과 근사 일치할 때만 SPDX를 부여하는데, Tencent 서문 3문단과 "Terms of the MIT License:" 구분선이 추가되어 유사도 임계값을 넘지 못한 것으로 보인다 [추정]. 조건 자체는 표준 MIT 문구(L9-13)와 문언상 일치하므로 SPDX 표기는 MIT로 취급하되, 자동 도구가 "other"로 보고하는 점을 컴플라이언스 스캐너 설정에서 수동 승인해야 한다.

이 도서(dossier)의 의무

  • MIT 고지 의무: "위 저작권 고지와 이 허가 고지(다음 문단 포함)를 복제본 또는 실질적 부분에 포함" LICENSE:L11. 본 도서는 짧은 코드 인용과 permalink를 쓰므로 "실질적 부분" 재배포에 해당하지 않을 가능성이 높다 [추정]; 그럼에도 안전하게 출처(Tencent/teamai-cli, commit 34e1cfb, MIT)와 저작권 표시("Copyright (C) 2026 Tencent")를 도서 하단에 병기한다.
  • 코드를 실질적으로 포함·수정·재배포하는 파생물을 만들 경우 LICENSE 전문(헤더 포함)을 동봉한다.
  • 보증 없음(AS IS) 조항 LICENSE:L13 — 채택 판단의 책임은 채택자에게 있다.

NOTICE · assets · vendor

  • pinned tree(579 엔트리)에 NOTICE, SECURITY.md, CODEOWNERS 파일 없음 (external-confirmed, tree-recursive.json). MIT는 NOTICE를 요구하지 않으므로 결함은 아니다.
  • assets/teamai-cli-icon.svg, teamai-cli-logo.svg, teamai-cli-mark.svg 3개 — 별도 라이선스 문구 없음. 리포 LICENSE가 기본 적용된다고 볼 수 있으나 [추정], 상표("Tencent", "TeamAI" 로고)는 MIT가 부여하지 않으므로 도서에 로고를 재사용할 때는 인용 수준으로 제한한다.
  • npm 배포물에 skills/·agents/ 콘텐츠가 포함된다 package.json:L9-L16; 별도 라이선스 표기 없음 → 리포 LICENSE 적용 [추정].
  • 의존성(SBOM 455개, devDeps 포함): licenseConcluded 집합에 MIT/ISC/Apache-2.0/BSD-2/3/BlueOak-1.0.0/CC0/Unlicense/CC-BY-3.0이 있고 GPL·LGPL·MPL은 없다 (external-confirmed, GitHub Dependency Graph 기준). 빈값 항목이 있어 전수 확인은 아니다.

unknown

  1. GitHub 탐지가 실패한 정확한 원인 (licensee 유사도 수치) — 위 설명은 추정.
  2. assets SVG의 원저작자/디자인 라이선스, Tencent 상표 사용 정책.
  3. SBOM에서 licenseConcluded가 빈값인 패키지들의 실제 라이선스.
  4. npm에 게시된 tarball의 LICENSE가 pinned 텍스트와 동일한지 (레지스트리 미조회).

이 섹션은 정적 파일 비교에 기반한 기술적 분류이며 법률 자문이 아니다.

11

주장 원장

README(핀 커밋 34e1cfb)의 실질적 주장 30건을 src/index.ts 명령 등록·docs/usage-guide.md·CHANGELOG.md·package.json·LICENSE·트리 인벤토리와 대조했다. 정적 검사만 수행했으며(실행·설치·빌드 없음), 구현 모듈이 검사 집합에 없는 주장은 unknown으로 둔다. 증거 종류: project-stated(저장소 문서의 자기 진술), static-support(코드·매니페스트·트리에서 확인), external-confirmed(외부 관측치), inference(추론).

주장 ID주장증거 종류출처 A출처 B판정신뢰충돌/열린 질문
C001Claude Code·Codex·CodeBuddy·WorkBuddy·OpenCode·Cursor 등 여러 에이전트에 걸쳐 skills/rules/MCP/knowledge를 관리project-stated static-supportREADME.md:L14src/index.ts:L18-L21, src/index.ts:L67partially-supportedmedium에이전트별 동기화 writer 모듈은 검사 범위 밖 — 툴별 지원 깊이 미검증
C002설치는 npm install -g teamai-cliproject-stated static-supportREADME.md:L30-L32package.json:L2-L6, docs/usage-guide.md:L88-L94supportedmediumnpm 레지스트리의 실제 게시 버전·dist-tag 미조회. 전제조건 Node ≥ 20, Git(TGit은 gf, CNB는 cnb CLI)은 README에 없음
C003init <repo>는 project 스코프 기본, --scope user로 홈 설치project-stated static-supportREADME.md:L45-L50src/index.ts:L51-L58, CHANGELOG.md:L117-L119supportedhigh
C004init 이후 모든 AI 세션 시작 시 자동 pull(수동 동기화 불필요)project-stated static-supportREADME.md:L53, docs/usage-guide.md:L414-L416src/index.ts:L88-L98, src/index.ts:L717-L757partially-supportedmedium충돌: README '모든 세션' vs usage-guide L416 — 훅 미지원 툴(JoyCode, Gemini CLI)은 수동 pull. 훅 본체(src/hooks.ts, src/hook-handlers.ts)는 다른 분석자 담당
C00511개 에이전트 × 13개 기능 축 지원 매트릭스project-stated static-supportREADME.md:L69-L96docs/usage-guide.md:L1356-L1377, CHANGELOG.md:L27unknownlow충돌: JoyCode는 usage-guide·CHANGELOG 0.23.0에 지원 대상이나 README 매트릭스에 행 없음. 143개 셀의 진위는 에이전트별 writer를 읽어야 판정 가능
C006Git 제공자 GitHub · GitLab · GitCode · CNB · TGit · 사설 Gitproject-stated static-supportREADME.md:L98, docs/usage-guide.md:L102트리 인벤토리 src/providers/{cnb,git,gitcode,github,gitlab,tgit}/ + src/providers/registry.ts (경로만 확인)supportedhigh충돌: CONTRIBUTING.md:L33-L36는 providers/github, tgit 두 개만 나열(문서 노후)
C007배포 제어 4종 projects/roles/tags/sourceproject-stated static-supportREADME.md:L104-L109src/index.ts:L226-L294, src/index.ts:L298-L489supportedhighpull 시 필터 적용 로직(src/pull.ts)은 다른 분석자 담당
C008learnings 격리: 루트 learnings/ 공유, learnings/<project-id>/ 프로젝트 전용project-statedREADME.md:L111docs/usage-guide.md:L196-L204, CHANGELOG.md:L9unknownlowCHANGELOG상 [Unreleased] 기능 — 어느 릴리즈에 포함되는지 불명(C026). 구현 경로 src/recall.ts·src/pull.ts 미검사
C009push → 브랜치+MR → 승인·머지 → SessionStart pull → 로컬 동기화project-stated static-supportREADME.md:L121-L125src/index.ts:L75-L98, CHANGELOG.md:L64partially-supportedmedium충돌: usage-guide:L333-L336 docs/hooks/mcp는 push가 아닌 직접 git commit; L1273 session save --push는 PR 없이 직접 커밋. MR 생성 본체는 다른 분석자
C010공유 리소스 11종(Skills…Models) 경로 표project-stated static-supportREADME.md:L131-L143src/index.ts:L111-L112, src/index.ts:L205-L206, docs/usage-guide.md:L1107-L1147partially-supportedmedium충돌: README Models '—' vs usage-guide의 ClawPro 모델 배포; remove는 실제 <type> <names...>이고 유형이 skills|rules|agents|mcp로 제한(docs/env/hooks 제거 불가)
C011Stop 훅이 friction(중단·정정·툴 거부·재시도)으로 점수화 후 /teamai-share-learnings 제안project-stated static-supportREADME.md:L155-L163, docs/usage-guide.md:L772-L784src/index.ts:L775-L785, docs/usage-guide.md:L1280-L1286partially-supportedmedium충돌: README·usage-guide L772는 'Stop 훅이 점수화'; contribute-check 설명(L777)과 내장 훅 표(L1284)는 기여 감지를 PostToolUse에 귀속. 점수 산식·임계치 코드 미검사
C012힌트는 세션당 최대 1회, sharing.contributeHint.enabled/contributeHintEnabled로 opt-out(Stop 훅 나머지 유지)project-statedREADME.md:L165docs/usage-guide.md:L795-L803, CHANGELOG.md:L29unknownlowdedup·opt-out 판독 코드(src/contribute-check.ts 미검사, src/config.ts·src/hook-handlers.ts는 다른 분석자) 본 분석자 미확인
C013/teamai-share-learnings 스킬이 learning 문서를 팀 저장소에 직접 pushproject-stated static-supportREADME.md:L165트리 skills/teamai-share-learnings/SKILL.md(내용 미검사), src/index.ts:L787-L798partially-supportedmedium'직접 push'가 기본 브랜치 커밋인지 MR인지 src/contribute.ts 미검사
C014Recall 기본 꺼짐, sharing.recall.enabled + 로컬 override, recall enable/disable/statusproject-stated static-supportREADME.md:L169-L175src/index.ts:L814-L839, docs/usage-guide.md:L820-L835partially-supportedmediumREADME 미기재 긴급 스위치 TEAMAI_RECALL_DISABLED=1(usage-guide L827). 기본 false 강제는 src/recall-toggle.ts·src/config.ts 확인 필요
C015pull이 teamai-recall 서브에이전트를 agents/에 배포, recall --check 사전검사project-stated static-supportREADME.md:L177src/index.ts:L802-L806, 트리 agents/teamai-recall.md, docs/usage-guide.md:L1343partially-supportedmedium배포 본체는 src/pull.ts(다른 분석자). hidden todowrite-hint(L841-L852)가 TodoWrite 때마다 recall 상기
C016recall <query>는 BM25 + graph-boost 검색project-stated static-supportREADME.md:L180-L187, L245src/index.ts:L802-L812, docs/usage-guide.md:L1194partially-supportedlow알고리즘 구현은 src/recall.ts(인벤토리만) 미검사
C017import --from-repo/--from-org, codebase --extract/--deep-enrich/--reconcile/--lintteamwiki/ 그래프 구축project-stated static-supportREADME.md:L193-L199src/index.ts:L854-L899, src/index.ts:L914-L934supportedhighREADME 예시의 --project/--output은 hidden 옵션(L919, L929). --deep-enrich가 로컬 AI CLI를 셸 호출(usage-guide:L1190)은 README 미기재
C018WASM tree-sitter AST 트랙 + 휴리스틱 트랙, AST_UNAVAILABLE 폴백, TEAMAI_SKIP_AST=1project-stated static-supportREADME.md:L205-L210docs/usage-guide.md:L1196, CHANGELOG.md:L57, 트리 src/wiki-engine/ 36항목unknownlow트리에 'wasm' 경로 0건(문법은 npm 의존성으로 [추정]). 판독 코드(src/codebase-extract.ts, src/wiki-engine/*) 미검사
C019codebase 페이지 recall 결과에 Sources: 줄 포함project-statedREADME.md:L202-L203unknownlowusage-guide에 대응 문장 없음; src/recall.ts 미검사
C020recall maintenance --prune --dry-run / --prune --archive / --update-qualityproject-stated static-supportREADME.md:L221-L223src/index.ts:L1000-L1076, docs/usage-guide.md:L837-L861supportedhighREADME 미기재 --confidence-writeback·--threshold(기본 0.15). --update-quality는 AI 초안을 .draft.md로 기록
C021recall promote [learningId]로 skills/rules/docs 승격project-stated static-supportREADME.md:L247src/index.ts:L1078-L1120, docs/usage-guide.md:L868-L881supportedhigh승격 기준(confidence ≥ 0.90, upvote ≥ 5, 기여자 ≥ 2, ≥ 14일)은 문서 진술 — src/maintenance/promote.ts 미검사
C022digest / session save / dashboard(웹 UI) 명령 존재project-stated static-supportREADME.md:L228-L233src/index.ts:L666-L702, docs/usage-guide.md:L1259-L1273supportedhighdashboard 기본 포트 3721. session save --push는 PR 없이 sessions/<user>/<YYYY-MM>.md에 직접 커밋; --include-prompt로 redacted 첫 프롬프트 포함 가능(기본 off)
C023digest 7일 지표(성공·프롬프트·활동시간·추정 비용·캐시·정정) + KB Health 페이지 구성project-stated static-supportREADME.md:L230-L233docs/usage-guide.md:L895-L917, L1232-L1255, 트리 src/dashboard*.ts, src/digest.tsunknownlow비용은 Claude 모델 ID 공개 단가 기반 추정치(청구서 아님, usage-guide L1255). 지표 산출 코드 미검사
C024Commands 표 27개 항목 전부 CLI에 등록static-support project-statedREADME.md:L237-L265src/index.ts:L51-L1120 (init L51, push L75, pull L88, status L100, skill exclude L149-L183, members L185, remove L205, packages L213, doctor L215, roles L226, projects L298, tags L337, source L418, uninstall L503, session save L670, digest L684, contribute L787, recall L802-L839, import L854, codebase L914, ci extract-mr L956, maintenance L1000, promote L1078)supportedhigh충돌: README L239 init 'OAuth login'은 index.ts L52 설명에 없음. 표 미기재 가시 명령 11종(list, skill show, update, env, hooks, mcp, stats, hook-dispatch, bind-project, review, recall feedback) + hidden 8종(track, track-slash, dashboard-report, contribute-check, todowrite-hint, mr-hint, deep-enrich, source reconcile-plugins)
C025라이선스 MITproject-stated static-supportREADME.md:L267-L269LICENSE:L1-L13, package.json:L47supportedhighLICENSE는 Tencent 서문("추가 제한 없음") + MIT 본문. 의존성 라이선스 미검사
C026CLI 버전 = package.json version; 이 커밋의 버전 식별은 일관돼야 함static-support project-stated external-confirmed inferencesrc/index.ts:L13-L21, package.json:L3 (0.22.0)CHANGELOG.md:L5-L22 ([Unreleased] → 0.23.0 2026-09-08), release.yml:L32-L37 (버전=태그 게이트)contradictedhigh충돌: package.json 0.22.0 vs CHANGELOG 0.23.0 릴리즈 기록 vs GitHub Releases 안정 v0.23.1 / 프리 v0.24.0-beta.6(도시에 컨텍스트 제공 관측치, 재조회 안 함). CHANGELOG에 0.23.1 항목 없음. release.yml 게이트상 태그 커밋은 package.json이 해당 버전인 별도 커밋이어야 함 — 핀 커밋의 package.json이 뒤처진 상태 [추정]
C027AGENTS.md(=CLAUDE.md) 규칙: 영어 출력·중국어 금지·Worktree 필수·새 명령 자제·이중언어 문서 동기화·PR 전 실제 e2eproject-stated static-supportAGENTS.md:L9-L24.github/CONTRIBUTING.md:L46-L48, 트리 CLAUDE.md(byte-identical은 도시에 컨텍스트 진술; 로컬 blob 부재로 cmp 미수행)not-applicablehigh충돌: AGENTS.md L9 기본 브랜치 main vs CONTRIBUTING.md L46 'branch from master'; AGENTS.md L21 실제 CLI e2e 필수 vs CONTRIBUTING.md L48 vitest+tsc만; AGENTS.md L15 중국어 금지인데 src/index.ts:L954 주석에 중국어(주석은 규칙 대상 밖일 수 있음 [추정])
C028teamai-hub 조직 템플릿에서 시작 가능project-statedREADME.md:L38unknownlow외부 조직 존재·내용 미조회
C029Packages는 npm 패키지 + Claude Code 플러그인만, packages [install] [target]project-stated static-supportREADME.md:L142, L242src/index.ts:L213, 트리 src/pkg/adapters/{npm,claude-plugin}.ts, docs/usage-guide.md:L429-L469partially-supportedmedium'pull이 서드파티 코드를 자동 실행하지 않음'(usage-guide L461)은 훅/pull 코드로 확인 필요(다른 분석자)
C030uninstall이 모든 teamai 리소스·훅 제거, 사용자 생성물 보존project-stated static-supportREADME.md:L265src/index.ts:L503-L512, docs/usage-guide.md:L1533-L1547partially-supportedmedium'사용자 생성물 보존' 판별 기준은 src/uninstall.ts 미검사. --dry-run 미리보기·--agent 단일 툴 제거 지원

집계: supported 10 · partially-supported 11 · contradicted 1 · unknown 7 · not-applicable 1 (총 30).

12

README 링크·미디어 처리

저장소 루트 입력이므로 README 완역은 산출물이 아니다(소스 코드가 SSOT, README는 주장). README는 11절 주장 원장의 입력으로만 썼다. 아래는 핀 README(README.md @ 34e1cfb35181, blob 7c0815bd)에 저자가 직접 쓴 링크·이미지 24건의 처리 결과다 — GitHub 크롬·내비게이션은 제외했고, 같은 URL의 반복은 각각 별도 항목이다. 이미지는 라이선스·상표·핫링크 근거가 확립되지 않아 재현하지 않았고(원격 요청 0), 링크는 안전한 절대 URL만 원래 의미 위치의 앵커로 보존했다.

  • 01[이미지 생략: teamai-cli]
    README.md L2 · document start
    image · omitted
  • 02English
    README.md L7 · TeamAI — Make Every Team AI Native
    link · preserved
  • 03简体中文
    README.md L7 · TeamAI — Make Every Team AI Native
    link · preserved
  • 04CI
    README.md L9 · TeamAI — Make Every Team AI Native
    link · preserved
  • 05[이미지 생략: CI]
    README.md L9 · TeamAI — Make Every Team AI Native
    image · omitted
  • 06npm version
    README.md L10 · TeamAI — Make Every Team AI Native
    link · preserved
  • 07[이미지 생략: npm version]
    README.md L10 · TeamAI — Make Every Team AI Native
    image · omitted
  • 08npm downloads
    README.md L11 · TeamAI — Make Every Team AI Native
    link · preserved
  • 09[이미지 생략: npm downloads]
    README.md L11 · TeamAI — Make Every Team AI Native
    image · omitted
  • 10License: MIT
    README.md L12 · TeamAI — Make Every Team AI Native
    link · preserved
  • 11[이미지 생략: License: MIT]
    README.md L12 · TeamAI — Make Every Team AI Native
    image · omitted
  • 12Contributors
    README.md L20 · Contributors
    link · preserved
  • 13[이미지 생략: Contributors]
    README.md L21 · Contributors
    image · omitted
  • 14contrib.rocks
    README.md L24 · Contributors
    link · preserved
  • 15https://github.com/yourorg/yourrepo` — 링크 차단(원문 href 형식 오류)
    README.md L36 · Team admin / solo user
    link · blocked
  • 16teamai-hub
    README.md L38 · Team admin / solo user
    link · preserved
  • 17docs/usage-guide.md
    README.md L55 · Team members
    link · preserved
  • 18中文版
    README.md L55 · Team members
    link · preserved
  • 19usage guide
    README.md L111 · Distribution Controls
    link · preserved
  • 20Usage Guide
    README.md L145 · What Gets Shared
    link · preserved
  • 21tree-sitter
    README.md L207 · Codebase Knowledge Graph
    link · preserved
  • 22usage guide
    README.md L259 · Commands
    link · preserved
  • 23MIT
    README.md L269 · License
    link · preserved
  • 24CONTRIBUTING.md
    README.md L273 · Contributing
    link · preserved
13

수집 범위·출처·실패

핀 커밋 · 트리34e1cfb35181241902b7058cedf98dedc5037dee · e3da6c2931d5e9d823c836928455cde0e7e82ed3
캡처 구간2026-09-11T04:49:47Z → 2026-09-11T05:01:01Z (약 12분)
API 버전요청 2022-11-28 · /versions 응답 [2026-03-10, 2022-11-28]
REST 요청33건 (2xx 29 · 401 4) — 기본 한도 45 이내, 미인증
Git 객체bare partial clone (blob:none, single-branch main, no tags, GIT_CONFIG_* 격리) + 핀 blob 534개 일괄 fetch; checkout/worktree 없음
정독 범위30파일 · 15,416줄 · 686,979바이트 (한도 30 / 20,000) · redaction 0 · 의존성 hop 1

구조화 소스 (endpoint · 상태 · 바이트 · sha256 앞 12자)

이름endpointstatusbytessha256observed
repository/repos/Tencent/teamai-cli2006,13835678fe7d03c04:49:48Z
ref-start/repos/Tencent/teamai-cli/git/ref/heads/main20033432124af88bc304:49:48Z
commit-pinned/repos/Tencent/teamai-cli/commits/34e1cfb35181241902b7058cedf98dedc5037dee20030,357b381450cf9b604:49:49Z
tree-recursive/repos/Tencent/teamai-cli/git/trees/e3da6c2931d5e9d823c836928455cde0e7e82ed3?recursive=1200138,676f8c00a5007a804:49:49Z
license/repos/Tencent/teamai-cli/license2002,8158ecafe9023e704:49:49Z
community-profile/repos/Tencent/teamai-cli/community/profile2001,030dbdeea7272e204:49:49Z
releases/repos/Tencent/teamai-cli/releases?per_page=1020076,479b1c5d768ee2b04:49:50Z
tags/repos/Tencent/teamai-cli/tags?per_page=102004,391ec06035123c504:49:50Z
commits-recent/repos/Tencent/teamai-cli/commits?sha=main&per_page=30200142,4757b9f8a29ee4b04:49:50Z
workflows/repos/Tencent/teamai-cli/actions/workflows200923a29dfa288c4804:49:51Z
workflow-runs/repos/Tencent/teamai-cli/actions/runs?branch=main&per_page=20200245,745ebf0eb13b5b404:49:51Z
check-runs-pinned/repos/Tencent/teamai-cli/commits/34e1cfb35181241902b7058cedf98dedc5037dee/check-runs20018,4741ce6d5bc5a2b04:49:52Z
issues-open/repos/Tencent/teamai-cli/issues?state=open&per_page=30&sort=updated&direction=desc200204,5358184372e15a004:49:52Z
issues-closed/repos/Tencent/teamai-cli/issues?state=closed&per_page=30&sort=updated&direction=desc200190,353576e2bddb33904:49:53Z
pulls-open/repos/Tencent/teamai-cli/pulls?state=open&per_page=30&sort=updated&direction=desc200114,45902d03dd0992a04:49:53Z
pulls-closed/repos/Tencent/teamai-cli/pulls?state=closed&per_page=30&sort=updated&direction=desc200551,225b5216e98155104:49:54Z
contributors/repos/Tencent/teamai-cli/contributors?per_page=3020028,488e095b411ff0704:49:54Z
languages/repos/Tencent/teamai-cli/languages20055495c2d04337f04:49:54Z
security-advisories/repos/Tencent/teamai-cli/security-advisories20024f53cda18c2b04:49:54Z
sbom/repos/Tencent/teamai-cli/dependency-graph/sbom200280,7765946d1a6d08204:49:55Z
branch-protection/repos/Tencent/teamai-cli/branches/main/protection401120b7dbd173f33b04:49:56Z
code-scanning-alerts/repos/Tencent/teamai-cli/code-scanning/alerts401120b7dbd173f33b04:49:56Z
dependabot-alerts/repos/Tencent/teamai-cli/dependabot/alerts401120b7dbd173f33b04:49:56Z
secret-scanning-alerts/repos/Tencent/teamai-cli/secret-scanning/alerts401120b7dbd173f33b04:49:56Z
topics/repos/Tencent/teamai-cli/topics200123913d8d7fcb104:49:57Z
api-versions/versions20027d5964be7d7cc04:50:17Z
issue-424-comments/repos/Tencent/teamai-cli/issues/424/comments?per_page=302007,083c45c5e46915b04:56:13Z
issue-492-comments/repos/Tencent/teamai-cli/issues/492/comments?per_page=302002,578ad406eac7cca04:56:13Z
issue-360-comments/repos/Tencent/teamai-cli/issues/360/comments?per_page=302003,92534c7bd079a0704:56:13Z
issue-17-comments/repos/Tencent/teamai-cli/issues/17/comments?per_page=3020027,7524f4cca0bc44804:56:14Z
issue-459-comments/repos/Tencent/teamai-cli/issues/459/comments?per_page=3020011,96140c5048d20c304:56:14Z
issue-471-comments/repos/Tencent/teamai-cli/issues/471/comments?per_page=302002,84291a54e310e1304:56:14Z
ref-end/repos/Tencent/teamai-cli/git/ref/heads/main20033432124af88bc305:01:01Z

401 응답 4건(branch protection · code scanning · dependabot · secret scanning)은 unknown이지 0이 아니다. 전체 해시·바이트·관측 시각은 evidence/index.json이 가리키는 github-sources.jsonl에 있다.

선택 파일 원장 (30 · 전부 full)

path범주object idbytescoverage
README.mddocs7c0815bd3527318,909full
LICENSEdocs935ff4be4d131,418full
package.jsonmanifest6215a0c345862,028full
AGENTS.mddocsb3a746b85c241,293full
.github/workflows/ci.ymlciaa3b9b57c91514,250full
.github/workflows/release.ymlci40c6711824882,890full
.github/CONTRIBUTING.mddocs99aa271284802,722full
docs/providers.mddocse8ba8e7f3a31317,166full
docs/designs/data-directory-layout.mddocs82efa6622028317,058full
docs/usage-guide.mddocsb932314de91,61689,207full
CHANGELOG.mddocsdd9a88c18a1,23676,704full
src/index.tssource6432abff5a1,12248,616full
src/init.tssourcebb3b11b1891,45757,605full
src/pull.tssource73cc9dd4af1,72075,884full
src/push.tssource42ac69bf9897239,297full
src/hooks.tssource1f038375e11,22249,761full
src/hook-handlers.tssource5f37a0c26651823,351full
src/config.tssource8a6dc74a6f43517,931full
src/api-key.tssource71ccfcf6fd531,905full
src/usage-tracker.tssourcec28910c15945014,944full
src/session-collector.tssource13d62b6fed2378,776full
src/utils/ai-client.tssourcebee9b63f3638413,451full
src/machine-id.tssource29e5aa5e991174,205full
src/bootstrap.tssource6d1ae318362369,782full
src/__tests__/init.test.tstest8d4f8dcc2c62120,520full
src/__tests__/hooks.test.tstest9076077a2576132,068full
src/__tests__/pull-skip-sync.test.tstest77ed80503b43214,852full
src/__tests__/push-pending-pr.test.tsteste1f85d57ad47919,211full
vitest.config.tsci70a5c7c2de17534full
vitest.e2e.config.tsci824488e69120641full

누락·경계

  • not-inspected — 504 of 534 blobs were inventoried (path, mode, object id, size) but not read. repository-root default bound of 30 substantive files
  • not-inspected — src/local-agent.ts (3429 lines), src/types.ts, src/recall.ts, src/codebase*.ts, src/dashboard*.ts, src/digest.ts, src/providers/*, src/wiki-engine/*, src/utils/* except ai-client.ts, 245 of 249 test files. bounded inspection; conclusions about these modules are marked unknown or project-stated
  • binary-or-asset — assets/*.svg (3 files). authored media not reproduced; SVG is never inlined (active-content isolation)
  • generated — package-lock.json (214,528 bytes). lockfile inventoried only; dependency facts taken from package.json and the GitHub SBOM endpoint
  • api-denied — branch protection, code-scanning, Dependabot and secret-scanning alert endpoints (HTTP 401 unauthenticated). recorded as unknown, never zero
  • pagination — releases/tags (10 each), commits (30), workflow runs (20), issues/pulls (30 per state), contributors (30), issue comments (6 issues). bounded single-page samples; not the full population

정적 전용 영수증

행위수행
checkout / worktreeno
dependency install / build / testno
run / import / containerno
hooks / submodules / LFS / filters / textconvno
execution-observed 증거unavailable (0건)

다음에 깨질 곳: 이 저장소는 하루 3.5건 릴리즈 속도라 이 문서의 file:line은 핀 커밋 34e1cfb35181에서만 유효하다. 재검토 시 hook-dispatch-cli.ts·contribute-check.ts·update.ts·local-agent.ts를 우선 정독하면 unknown 4건이 닫힌다.