@hyungjuk/sprint
v1.2.0
Published
Sprint work management CLI and server
Readme
Sprint
공식 CLI 문서 · 명령 레퍼런스 · AI 사용 안내
기존 업무 UI를 보존한 독립 Node 웹 앱과 HTTP CLI입니다. 프로젝트의 PBL·마일스톤·스프린트·칸반·타임라인·데일리 스크럼·개요, 회고, 조직 관리와 실제 /four-dx/goals, /four-dx/scoreboard, /four-dx/weekly 화면을 제공합니다. 179개 도메인 동작의 실제 HTTP/CLI 왕복 검증을 제공하며 명령은 node cli.mjs --help와 docs/web-cli-parity.md를 확인하세요.
CLI 설치와 업데이트
배포 이름은 @hyungjuk/sprint이고 명령 이름은 sprint입니다. 기본 설치 명령은 다음과 같습니다.
npm install --global @hyungjuk/sprint
sprint --version
sprint --help특정 버전을 공개 tarball URL로 직접 설치할 수도 있습니다.
npm install --global https://registry.npmjs.org/@hyungjuk/sprint/-/sprint-1.0.0.tgz소스 체크아웃에서 설치하려면 npm run install:cli를 실행합니다. 기존 work 명령은 호환 별칭으로 제공되며, 기존 로그인 세션 위치와 WORK_* 서버 설정도 유지합니다.
npm의 sprint 및 sprint-cli는 다른 프로젝트의 패키지입니다. 이 프로젝트의 배포 이름은 @hyungjuk/sprint입니다. 배포자는 npm login 후 npm publish로 게시합니다. publishConfig.access는 public으로 설정되어 있습니다. npm 전역 설치 방식은 npm 설치 문서를 따릅니다.
현재 로컬 배포 파일이 있으면 npm install --global ./dist/hyungjuk-sprint-1.1.0.tgz로 설치할 수 있습니다.
원격 서버 없이 배포 파일을 공유하려면 npm pack으로 생성한 hyungjuk-sprint-1.1.0.tgz를 전달하고 npm install --global /path/to/hyungjuk-sprint-1.1.0.tgz로 설치할 수 있습니다.
sprint update # 최신 버전 확인 후 y/n 입력 (기본 n)
sprint update --yes # 확인 없이 업데이트
sprint update --no # 업데이트 취소; 네트워크 요청 없음
sprint update --yes --non-interactive
SPRINT_AUTO_UPDATE=0 sprint issues list공개 패키지를 전역 설치한 뒤에는 대화형 터미널에서 업무 명령 실행 시 최신 안정 버전을 자동 설치하고 새 버전으로 명령을 실행합니다. npm 설정의 registry와 기존 설치 prefix를 그대로 사용합니다. 버전 확인 제한은 3초, 설치 제한은 120초입니다. 실패하면 안내 후 기존 버전으로 업무 명령을 계속합니다. --help, --version, 스키마 조회, MCP 서버, 파이프/CI 및 --non-interactive에서는 자동 업데이트하지 않습니다. 비대화형 수동 업데이트에는 --yes 또는 --no를 명시해야 합니다.
소스 체크아웃(npm run install:cli 포함)은 npm 자동 업데이트 대상이 아닙니다. 소스 설치는 새 소스로 다시 설치하세요. npm으로 전역 설치한 @hyungjuk/sprint 패키지는 같은 npm 이름의 최신 안정 버전으로 업데이트합니다. 업데이트는 CLI 패키지만 교체하며 별도로 실행 중인 서버를 재시작하지 않습니다.
AI 에이전트에서 사용하기
CLI 설치와 에이전트 연결은 별도입니다. npm으로 설치하면 sprint 실행 파일이 PATH에 추가되지만, 에이전트가 그 존재와 사용 시점을 자동으로 알게 되는 것은 아닙니다.
현재 제공하는 문서와 도구
npm install --global @hyungjuk/sprint
sprint --version
sprint issues --help
sprint --schema issues
sprint --llms
sprint --llms issues--help는 전체 명령 그룹, 그룹의 바로 아래 하위 명령, 개별 명령의 문법·예시·관련 정책을 단계별로 보여 줍니다. sprint help -- 검색어로 설명과 플래그도 검색할 수 있습니다. --schema DOMAIN은 API 동작 계약 JSON, --llms는 짧은 AI 안내, --llms DOMAIN은 도메인 동작 계약 JSON입니다. API 계약의 입력과 실제 CLI 플래그는 서로 다를 수 있으므로 실행할 하위 명령의 도움말도 확인해야 합니다. 이러한 조회에는 Sprint 서버 로그인이나 네트워크 연결이 필요하지 않습니다.
업무 명령은 서버 연결과 Sprint 인증이 필요합니다. npm 로그인은 패키지 배포용이며 Sprint 서버 로그인과 다릅니다. 기존 세션을 쓰거나, 이미 발급받은 private 0600 자동화 토큰 파일을 --token-file /absolute/private/token.json으로 전달하세요. AI 작업은 --non-interactive를 사용하고 stdout의 JSON 응답과 종료 코드를 읽습니다. 비대화형 실행에서는 CLI 시작 시 자동 업데이트를 생략합니다.
프로젝트에서 사용하도록 알려 주기
Codex 프로젝트의 기존 AGENTS.md에 다음과 같은 규칙을 병합할 수 있습니다. 기존 규칙 파일을 덮어쓰지 마세요. 다른 에이전트는 그 에이전트가 지원하는 프로젝트 지시 파일에 같은 정책을 둡니다.
## Sprint 작업 관리
이 프로젝트의 이슈·스프린트·진행 상황은 Sprint에서 관리한다.
관련 요청이 오면 Sprint CLI 또는 등록된 Sprint MCP 도구를 우선 사용한다.
CLI 실행 파일은 sprint이고 npm 패키지는 @hyungjuk/sprint다.
- 최초 사용 시 sprint --version과 sprint whoami --non-interactive로 설치와 인증을 확인한다.
- 명령을 추측하지 말고 실행할 하위 명령의 --help를 먼저 확인한다.
- 필요하면 sprint --schema issues 등 관련 도메인의 계약만 조회한다.
- 연결된 프로젝트와 대상 이슈를 확인한 후 사용자가 요청한 범위에서 조회·변경한다.
- 단순 질문이나 코드 열람만으로 이슈를 새로 만들거나 완료 처리하지 않는다.
- 변경 전 현재 레코드와 리비전을 확인하고, 변경 후 서버 응답으로 결과를 검증한다.
- 자동화에서는 --non-interactive를 사용하고 토큰 내용은 출력하지 않는다.
- 인증/권한이 없으면 작업 관리가 반영됐다고 주장하지 말고 필요한 설정을 알린다.프로젝트와 Sprint workspace/project의 연결 정책도 함께 정해야 합니다. 명령 설치만으로 어느 서버·프로젝트에 작업을 기록해야 하는지 결정되지 않습니다. AGENTS.md 같은 규칙은 모델의 행동 지침이며 실행을 강제로 보장하는 장치는 아닙니다.
MCP로 도구 목록에 노출하기
Sprint에는 이미 stdio MCP 서버가 있습니다. 인증된 기본 프로필이 준비된 Codex 환경에서는 다음처럼 등록할 수 있습니다. 이 명령은 예시이며 이 문서 작성 중 사용자 에이전트 설정을 변경하지 않았습니다.
codex mcp add sprint -- sprint mcp serve --profile default --domains issues,workTeams--domains는 노출 범위를 제한합니다. 실제 서버 권한과 Sprint 인증이 적용되며, CLI와 MCP는 같은 업무 API를 사용합니다. --read-only를 사용하는 MCP는 서버가 강제하는 read 범위의 자동화 토큰 파일이 필요합니다. MCP 연결은 도구 발견을 돕고, 위 프로젝트 규칙은 언제 해당 도구를 사용할지 알려 줍니다.
Google Cloud CLI에서 참고할 방식과 다음 개선
Google은 명령별 도움말과 검색, 구조화된 출력과 비대화형 실행, 별도 공식 gcloud Agent Skill을 함께 제공합니다. 해당 Skill은 정확한 하위 명령의 로컬 도움말 확인과 출력량 제한을 지시합니다. Google Skills는 CLI 자체와 별도로 설치·업데이트됩니다.
Codex 역시 AGENTS.md와 Skills를 구분하며, 공식 MCP 연결 안내도 도구를 안정적으로 사용하게 하려면 프로젝트 지시를 함께 두도록 안내합니다.
Sprint에 다음으로 추가할 기능은 프로젝트 연결, 에이전트별 Skill 설치, 기존 지시 파일에 사용 규칙 병합, 선택적 MCP 등록을 돕는 명시적 설정 명령입니다. 현재는 이러한 통합 설정 명령이나 배포된 Sprint Agent Skill이 없습니다. npm 설치 후 임의로 전역 AI 지시나 다른 프로젝트의 설정을 수정하지 않습니다.
도움말은 짧은 명령 목록 → 하위 명령의 인자/예시 → 필요한 도메인 JSON 계약 순서로 읽습니다. 전체 --help는 약 3.6KB, --llms는 약 1.9KB입니다. npm run docs:generate가 같은 명령 정의와 도움말 렌더러로 docs/cli/ Markdown 문서를 생성하고, npm run docs:check 및 prepack 검사로 문서 불일치를 검출합니다. 공개 문서는 sprint-docs에서 제공합니다.
실행
Node ^22.22.2 || ^24.15.0 || >=26.0.0이 필요합니다. 검증 런타임은 Node 24.15.0입니다.
npm ci
cp .env.example .env
# .env의 세 WORK_BOOTSTRAP_* 값을 직접 입력하세요.
node --env-file=.env server.mjs.env는 자동으로 읽지 않습니다. 기존 환경에서 npm start를 쓰거나 위 Node 옵션을 명시하세요. 기본 주소는 http://127.0.0.1:4331 입니다. 비밀번호는 SQLite 8–256자, PostgreSQL 20–256자이며 신규 DB에서만 사용합니다. 초기 계정과 구성원은 최초 시작에서 한 번 생성됩니다. 기존 DB 재시작 시 계정/비밀번호를 덮어쓰지 않습니다. 구성원 ID는 workspace-owner이고 이름·이메일은 설정값입니다. 원본 사용자, DB, 쿠키, 캐시가 필요하지 않습니다.
node cli.mjs login --base-url http://127.0.0.1:4331 --email YOUR_EMAIL --password-stdin
node cli.mjs whoami
npm test
node scripts/verify-independent.mjsCLI 로그인은 표준입력으로 비밀번호를 받습니다. HTTP는 loopback에만 허용하고 HTTPS는 검증된 대상 URL을 사용합니다. CLI는 서버 API만 호출하며 DB를 직접 다루지 않습니다.
독립 설정
| 설정 | 의미 / 기본값 |
| --- | --- |
| PORT | 4331, 1–65535 |
| WORK_BIND_HOST | 127.0.0.1; 0.0.0.0 또는 ::1 허용 |
| WORK_PUBLIC_ORIGIN | 선택; 정확한 HTTPS origin 또는 HTTP loopback origin |
| WORK_TIME_ZONE | Asia/Seoul; 유효한 IANA 시간대. 서버 업무 날짜와 4DX 생략 검색조건에 적용 |
| WORK_DB_PATH | 앱 루트 local.sqlite; SQLite 파일 경로 |
| WORK_DATABASE_URL | 선택; 명시하면 기존 PostgreSQL 어댑터 사용 |
| WORK_BOOTSTRAP_EMAIL/NAME/PASSWORD | 신규 DB 최초 관리자 설정; 기본 개인정보/비밀번호 없음 |
| WORK_PG_ALLOW_PRIVATE_NETWORK | 0; 기존 PG private-network 정책의 명시 허용 |
| WORK_PG_REQUIRE_VERIFIED_TLS | 0; 1이면 인증서 검증 TLS 강제 |
| WORK_PG_ALLOW_PLAINTEXT | 0; 기존 PG 평문 정책의 명시 허용 |
기존 E2E_*, AXHUB_*, 일반 DATABASE_URL은 읽지 않습니다. SQLite/PG 선택과 PG 플래그는 서버에서 어댑터에 명시 전달합니다. 쿠키는 work_execution_session, SameSite=Strict/HttpOnly이며 공개 HTTPS origin 설정 시 Secure입니다. 원본 쿠키는 인증되지 않습니다. AxHub SDK·서버 SSO 경로·프로필 사진 schema·급여일 계산·매출 복원 문구와 프로필 전용 코드를 제거했습니다. 조직에 필요한 Slack ID 검증 두 함수만 기존 helper에 남아 있으며 정적 제공하지 않습니다. 원본과 같은 바이트를 요구하는 CSS에는 과거 선택자가 남아 있지만 제외 기능의 실행 경로는 없으며 외부 인증 API는 404입니다. 인증 모듈은 기존 로컬 폼/수명 처리를 유지하면서 외부 인증 분기를 제거했고, 선언된 유일한 역변환으로 원본 전체 SHA를 검증합니다. SW는 공개 정적 allowlist만 저장하며 API·사용자 응답은 캐시하지 않습니다.
독립 설치 검증과 저장소
이 디렉터리 자체가 새 Git 루트입니다. .gitignore를 먼저 작성한 뒤 초기화했으며 스테이징·커밋·원격 생성·푸시는 하지 않았습니다. DB/WAL/SHM·node_modules·환경파일·세션·캐시·로그·작업 기록은 Git 후보에서 제외합니다. 백업은 별도로 관리하세요.
scripts/product-files.json이 배포 복사의 명시 allowlist입니다. 검증 명령은 접근 권한 0700 임시 폴더에 이 파일만 복사하고, 원본/형제 체크아웃·node_modules·.git·.superpowers·환경파일·세션·DB 없이 npm ci, npm test, 신규 시작/로그인, 실제 CLI 조직·계정·설정·초대 수락·프로젝트·4DX 생성/정정 및 HTTP 저장값 대조, 정적 자산, 3개 HTML 경로, 기존 DB 재시작 보존를 검사하고 정리합니다. npm test는 이 명령을 재귀 실행하지 않습니다. 설치에는 npm registry 접근이 필요합니다. SQLite는 기본 테스트와 독립 설치에서 검증합니다. PostgreSQL은 별도 명시 명령으로 전용 loopback 클러스터에 임시 DB를 만들어 같은 CLI 흐름, SQL 트랜잭션·롤백, 기존 데이터 마이그레이션과 재시작을 검증한 뒤 삭제합니다. 기본 npm test는 PostgreSQL 연결을 요구하거나 미연결을 skip/pass로 처리하지 않습니다. 실제 실행 결과와 브라우저 인수 범위는 docs/acceptance-results.md를 따릅니다.
출처와 라이선스
사용자 소유 작업공간의 e2e-local 업무 범위를 읽기 전용으로 추출한 기반입니다. source-baseline.json의 원본 SHA는 제외 파일도 포함하는 역사 자료이며 현재 배포 allowlist가 아닙니다. tests/fixtures/source-preservation.json은 원본 CSS·방법론·업무 구간·Loopy·그림/폰트의 원본 SHA와 출처를 동봉하여 형제 체크아웃 없이 검증합니다. Loopy의 승인된 4DX 추가 부분은 유일한 마커와 선택 매개변수를 역변환한 뒤 원본 SHA를 확인합니다. 원본 해시를 현재 해시로 바꾸지 않습니다.
원본 루트의 별도 소스 라이선스는 발견되지 않았습니다. 이 추출이나 Git 초기화가 외부 재배포 허락을 부여하지 않습니다. Pretendard의 SIL Open Font License는 public/media/fonts/LICENSE.txt에 보존했습니다. npm 의존성의 개별 라이선스는 각 패키지에 따릅니다. 원문 요구사항은 docs/specs/work-execution-handoff.md, 계획은 docs/superpowers/plans/2026-10-22-work-execution-web-cli.md, 화면 증거는 docs/html-baseline.md입니다. 문서 속 원본 절대 경로는 참고 출처이며 운영·테스트 의존성이 아닙니다.
최종 검증의 범위
tests/capability-parity.test.mjs는 179개 동작을 실제 CLI로 실행하고 HTTP 저장값, 목록, 상태, 이력과 효과를 확인한 뒤에만 실행 증거에 등록합니다. domain-capabilities.mjs의 verified는 이 자동 HTTP/CLI 계약 검증을 뜻합니다. 각 동작의 테스트 파일·정확한 이름·필드 증거는 docs/web-cli-parity.md에 있습니다. 실제 브라우저 전체 동작 179회를 수행했다는 의미는 아닙니다. 원본 업무 회귀, 세 폭, 키보드, 0/N/A, 충돌, 세션 격리와 offline 복귀는 별도 브라우저 증거입니다.
# 선택: 본인이 관리하는 전용 PostgreSQL loopback 클러스터만 지정
# 0600 일반 JSON 파일: {"url":"postgresql://..."}; CREATE/DROP DATABASE 권한 필요
node scripts/verify-postgres.mjs --credentials-file /private/path/credentials.json
npm pack --dry-runPostgreSQL 검증은 환경변수에서 자격증명을 찾지 않습니다. 파일의 비밀번호·URL·세션을 출력하지 않으며 새로 만든 DB만 변경/삭제합니다. TLS를 사용하는 운영 환경·외부 PG 서비스·실제 모바일 기기는 이 로컬 검증 범위 밖입니다.
이전 4DX 자료의 최초 업그레이드는 영속 리비전 가드를 추가합니다. 이전에 열어 둔 클라이언트는 충돌 시 다시 불러오며 이후 재시작에는 리비전이 유지됩니다. 기존 업무의 선택적 리비전 계약은 유지합니다.
PWA는 공개 정적 자산만 캐시합니다. 오프라인에서는 사용자 API를 재생하지 않으므로 업무 데이터를 사용하는 앱 전체를 오프라인으로 이용할 수 없습니다. 온라인 복귀 후 서버에서 현재 세션과 데이터를 다시 읽습니다.
브라우저 검증자는 새 ego-browser nodejs 실행 파일에서 다음처럼 기존 TaskSpace/인증된 Page를 사용합니다. 숫자와 주소·출력 폴더는 검증자 소유 fixture 값으로 바꿉니다. 출력 폴더는 아직 존재하지 않는 절대 경로여야 합니다.
const {runAcceptance} = await import('/absolute/work-execution/scripts/ego-acceptance.mjs');
const report = await runAcceptance({spaceId: 41, baseURL: 'http://127.0.0.1:PORT', outputDirectory: '/absolute/new-round'});
console.log(report);이 함수는 기존 Page의 세 4DX 경로, 1440/1024/390 CSS 폭, 로드 완료, 오류 관찰자와 정적 캐시를 읽고 스크린샷을 저장합니다. 실행자는 이미지를 직접 확인해야 합니다. TaskSpace 생성·종료, 로그인, 도메인 쓰기, 프로필 캐시 삭제를 수행하지 않습니다. 현재 분기·소유자 문맥은 routes 배열의 URL query로 전달할 수 있습니다. 쓰기/세션 격리/offline 검증은 별도 round에서 수행합니다.
GitHub issue synchronization is opt-in. github import imports Issues (excluding
pull requests) page by page; persist its returned cursor to resume after an
interruption. github pairs list/get exposes authorized pair IDs and revisions;
github pairs and github pairs create pair an existing native issue. A new
manual pair is disabled until github enroll explicitly enables it. Existing
connection defaults remain false. github sync queues a revision-checked run;
github status reports the durable job and current field conflicts. All commands
use the product session/token-file, not gh authentication or App keys.
Native issue changes project their journal event and durable queue identity in
the same database transaction. sync.state=queued means the native change
committed; synced requires matching current native/provider readback. A provider
write whose response/readback was lost remains uncertain and is reconciled
without blindly repeating the mutation. Every outbound issue PATCH or sub-issue
operation has its own durable identity, including changes discovered by recovery.
Title, description, open/completed/canceled state, verified assignee IDs, mapped
labels, explicit priority-label mappings and verified parent relations participate
in per-field comparison. Different simultaneous edits conflict only in their
field; independent fields can progress. Open GitHub state preserves native doing
and review. Canceled workflow state maps to not_planned; an unavailable or
ambiguous native canceled state is a mapping conflict. Date and estimate remain
native. Priority labels must be explicitly mapped and mutually exclusive; the
application never invents labels.
GitHub's generic parent endpoint 404 can mean no parent or an inaccessible private parent. Missing/null parent hints do not prove absence. Such observations retain an explicit parent field conflict and never clear an existing native parent; other fields continue. A known parent relation uses the documented parent and sub-issue endpoints with numeric REST issue IDs. Cross-repository parent calls require current native authority and freshly verified installation scopes for both repositories; only those specialized calls may mint a token scoped to exactly those two repositories. Removal verifies the known parent's complete sub-issue inventory; this proves removal of that relation, not global visibility of every possible parent. Consequently ordinary issues with an ambiguous parent read can have converged title/body/state while overall status remains conflict.
Fresh remote reads, local revision checks and post-write readback detect many concurrent edits. GitHub issue PATCH has no atomic compare-and-swap guarantee; an external edit in the remaining read/write interval can still race. Remote transfer preserves a pair only after fresh target scope/authority and the exact stored REST ID plus node ID are verified; native project/team movement uses the shared issue command and preserves UUID/old ticket aliases. Unverified transfer or location is paused. Deletion retains a tombstone and never deletes the other side. These behaviors are exercised with owned loopback App-provider fixtures; live GitHub App acceptance remains a separate gate.
GitHub synced comments
Native issues comments add|reply JSON/file input accepts visibility: "internal"
(default) or "synced". Visibility and thread parent are fixed at creation; a
later change returns409. Internal and legacy comments never enqueue provider writes,
including edits and deletion. Synced comments follow their currently enrolled issue
pair and connection; replies retain their native thread while GitHub issue comments
remain flat. Current native author, issue, thread and connection authority are checked
again at dispatch and confirmation.
github comments status --json-data '{"commentId":"COMMENT_UUID"}' returns only
commentId, visibility, revision, pairId and sync metadata. Native commits return
queued/running work separately from verified synced readback. Remote public comments
appear with visibility synced and safe providerAuthor attribution; native ownership
and the authenticated journal actor remain separate. Bodies are literal text.
Timeouts keep the same durable operation uncertain; use github jobs reconcile
with its displayed revision to read back the accepted result. No uncertain create,
edit or delete is blindly replayed. A refused provider edit/delete or divergent
edit is a conflict and never creates a replacement comment. Recovery exhausts comment
pages and rereads current provider state, including deletion and reordered webhook
notifications. Existing issue field conflicts keep recovery incomplete while its
independent paired comment observations can still progress.
GitHub conflict management and operations
Use the product CLI session to inspect current authorized conflicts across issue fields, PR status automation, and explicitly synced comments:
node cli.mjs github conflicts list --json-data '{"connectionId":"CONNECTION_UUID"}'
node cli.mjs github conflicts get --json-data '{"id":"CONFLICT_UUID"}'
node cli.mjs github conflicts preview --json-data '{"id":"CONFLICT_UUID","resolution":"fields","fields":{"name":"Selected title"}}' --expected-revision CONFLICT_REVISION
node cli.mjs github conflicts apply --json-data '{"previewId":"PREVIEW_UUID"}' --expected-revision PREVIEW_REVISION
node cli.mjs github doctor --json-data '{"connectionId":"CONNECTION_UUID"}'Pass the revision displayed by get to preview, then the preview's own revision
to apply. A preview belongs to the creating principal and expires after five
minutes (HTTP 410). Subsequent native/provider/connection changes reject apply
with HTTP 409. Current issue, comment/thread, and connection permissions are
checked again at apply; revoked access is denied even for an existing preview.
resolution accepts keep-local, use-remote, or fields. Only fields accepts
a fields object, limited to the conflicted field's native keys: name (title),
description (body), status/stateId, assigneeId, labelIds, priority, or
parentIssueId. PR automation selects status (todo, doing, review, done);
comment conflicts select body and/or boolean deleted. Missing mappings and
unverified parents remain explicit conflicts. Resolution cannot resurrect a
comment, replace a deleted provider comment, bypass a provider refusal, or
re-dispatch an uncertain operation.
Issue-field resolution accepts the freshly observed provider value as its comparison baseline and queues durable synchronization; keeping/customizing the local value intentionally leaves an outgoing difference. Comment resolution updates the observed baseline and queues an edit/delete only when needed, keeping the original pair and author. PR resolution records the selected native status and revision as its automation baseline without queuing a provider mutation. Every accepted resolution records an audit. Future independent PR-policy changes may propose another transition from that accepted baseline. A fresh provider read cannot eliminate GitHub's external read-to-write race; local acceptance is not a claim that remote synchronization has already finished.
github jobs list|get|retry|reconcile inspects safe metadata and manages durable
work; retry/reconcile require the job's displayed revision. github recover
performs missed-webhook recovery and reports incomplete scopes/cursors separately
from job retry. github doctor separates disabled/configured App, scoped API
readiness, configured HTTPS webhook URL, and observed signed business deliveries.
A signed local ping creates no connection or business job and proves no external
reachability. App installation, public ingress, and live GitHub acceptance require
separate configuration and evidence; these commands do not create a tunnel.
Product CLI and stdio MCP
The product MCP connects to this application's HTTP service with its private profile or automation-token file. It is separate from Linear's hosted MCP and authentication. No hosted MCP endpoint or external SaaS runtime dependency is introduced.
node cli.mjs --schema issues
node cli.mjs --llms github
node cli.mjs mcp serve --profile default --domains issues,workTeams,github
node cli.mjs auth tokens create --json-data '{"name":"Read automation","scope":"read"}' --output-file /private/path/read-token.json
node cli.mjs mcp serve --token-file /private/path/read-token.json --read-only --domains issues,workTeams
node cli.mjs issues branch APTA-123 --directory '/path/with spaces/repository'
node cli.mjs issues update APTA-123 --title 'Ready for review' --wait --timeout 30MCP groups actions into list/get/save/action tools. tools/list is paginated; --domains limits exposure, while the HTTP server always checks current permissions. Tool arguments contain action, input, and optional expectedRevision / operationKey. New actions use their contract input unchanged; native REST actions use {id?, issueId?, email?, query?, data?}. Discover exact input schemas through tools/list or --schema [DOMAIN] (schema version 1.0.0).
Read-only MCP requires an actual server-enforced read automation token, confirmed using authenticated identity introspection. A session or read-write token is refused. Expiry, revocation, disabled accounts and current project/action permissions apply on every request. There is no automatic login or mutation retry. Files retain current-owner, no-symlink, private-directory and 0600 rules.
automationTokens.create requires a top-level MCP outputFile pointing to a new exclusive 0600 file; its raw token is consumed before result formatting. Only metadata and the output path appear in the tool result. Native invitation creation uses input.outputFile, and password-based native actions require input.secretFile; invitation lookup uses input.tokenFile. These files never appear as raw secret tool arguments. CLI invitation --token-file keeps its original invitation-secret meaning.
--wait observes the accepted job ID, including durable readback completion. Timeout (exit 10) and Ctrl-C (exit 130) stop observation and report jobId / localCommitted: true; accepted work continues. A terminal conflict remains a conflict even when one field has converged. Branch creation reads the authorized ticket and its unique active repository connection, checks the local origin, and passes generated branch names as argv. It never stashes, commits, pushes or resets local changes.
S3 preserves all 267 adopted action mappings. The 22 planning, productivity and execution-link actions assigned to C5/C6/C7 await their service acceptance; their presence in schema is not execution proof. The S3 checkpoint records actual installed-service invocation, schema/token measurements and the remaining M3 browser/PostgreSQL/live-provider gates. Authenticated Linear catalog verification remains unavailable (live_mcp_catalog_verified=false).
AxHub SSO와 CLI 인증
배포에서 WORK_AXHUB_SSO_ENABLED=1과 고정 WORK_PUBLIC_ORIGIN, WORK_AXHUB_API_ORIGIN, WORK_AXHUB_CONSOLE_ORIGIN, WORK_AXHUB_TENANT_ID, WORK_AXHUB_TENANT_SLUG, WORK_AXHUB_SUBJECT_BINDINGS를 설정합니다 (.env.example 참고). API·콘솔은 경로 없는 정확한 HTTPS origin이어야 합니다. 바인딩 JSON은 검증한 Hub subject UUID를 기존 계정 이메일에 연결합니다. Hub 역할·이메일만으로 사용자나 관리자 권한을 만들지 않습니다. 기존 workspace-owner 및 native ACL을 유지합니다.
브라우저는 HttpOnly _hub_access 쿠키를 공식 SDK로 검증하고 매 인증 요청마다 현재 활성 tenant membership을 확인합니다. Hub 세션이 없으면 설정된 공식 로그인 화면으로 이동합니다. 앱 로그아웃은 이 앱 세션만 제거하고 자동 재로그인을 막습니다. 다시 들어가려면 AxHub로 계속하기를 누릅니다. 전역 AxHub 세션은 유지됩니다. provider 오류와 권한 거부는 로그인 리다이렉트를 반복하지 않고 화면에 표시합니다.
CLI에서 바로 AxHub 로그인할 수 있습니다. 별도 AxHub CLI 설치는 필요하지 않습니다.
sprint login --axhub
# 브라우저에서 AxHub 인증 승인 → 터미널에서 테넌트 선택 → Sprint 서버 자동 연결
sprint whoami
sprint projects list
sprint logout
# 테넌트 또는 서버를 직접 지정하거나 별도 프로필에 저장
sprint login --axhub --tenant jocodingax --profile company
sprint login --axhub --tenant jocodingax --base-url https://work-execution.jocodingax.axhub.ai
# 브라우저를 열 수 없는 환경: 표시되는 인증 주소를 직접 열어 승인
sprint login --axhub --tenant jocodingax --no-browser --non-interactiveAxHub 공식 CLI와 같은 OAuth 기기 인증을 사용하고, 인증 후 활성 테넌트 중에서 선택합니다. 해당 테넌트의 접근 가능한 sprint 또는 work-execution 앱을 찾습니다. 앱이 여러 개면 추가로 선택하며, 다른 앱 이름으로 배포한 경우 --base-url을 지정합니다. 비대화형 실행은 --tenant가 필요하며 브라우저 승인은 여전히 필요합니다. 테넌트와 서버 설정을 대조하고 기존 계정 연결·재직 상태를 확인한 뒤, 8시간 유효한 제품 인증 정보를 현재 CLI 프로필에 저장합니다. Hub 토큰과 브라우저 쿠키는 파일에 저장하지 않습니다. 만료되면 다시 로그인하세요. logout은 해당 제품 인증 정보만 폐기하며 AxHub 전역 로그인은 유지합니다.
서버에도 이 버전의 /api/auth/axhub/cli 엔드포인트와 기존 AxHub SSO 설정이 필요합니다. CLI만 업데이트하고 서버를 업데이트하지 않으면 로그인할 수 없습니다. 독립형 설치의 이메일·비밀번호 로그인은 기존 명령을 유지합니다.
sprint login --base-url http://127.0.0.1:4331 --email YOUR_EMAIL --password-stdinCLI/MCP의 명시적 scoped automation token 파일도 계속 지원합니다. 제품의 토큰 발급 기능에서 {baseURL,token} JSON을 서버/사용자 소유의 안전한 디렉터리 안 새 0600 파일로 저장한 후 아래처럼 검증하고 사용합니다. 기존 세션 파일을 갖춘 독립형 설치에서는 work auth tokens create ... --output-file /absolute/private/token.json도 사용할 수 있습니다. SSO 배포에서는 비밀번호 CLI 로그인과 Hub 쿠키 복사를 사용하지 않습니다.
node cli.mjs login --token-file /absolute/private/token.json --non-interactive
node cli.mjs whoami --token-file /absolute/private/token.json --non-interactive
node cli.mjs mcp serve --token-file /absolute/private/token.json --non-interactive --read-onlylogin --token-file은 인증된 identity API로 credential을 검증하고 안전한 사용자·성공 정보만 출력합니다. 토큰을 출력하거나 로컬 로그인 세션으로 저장하지 않습니다. 이후 명령에도 같은 --token-file을 지정합니다. 파일은 현재 사용자 소유의 regular 0600 파일이어야 하며 심볼릭 링크·하드 링크·다른 profile/URL과의 혼합은 거부합니다. 원격 URL은 HTTPS만 허용합니다. 기본 SSO 비활성 설치의 기존 --base-url ... --email ... --password-stdin 로그인은 유지됩니다.
External Inbox notifications
Set WORK_MAIL_ENABLED=1 to queue assignment, mention and subscribed-comment email through AxHub's official app messaging SDK. This requires WORK_PUBLIC_ORIGIN, the trusted https://api.axhub.ai SSO configuration, explicit WORK_AXHUB_SUBJECT_BINDINGS, and the deployment-injected AXHUB_APP_TOKEN. Each existing native email must map to exactly one Hub subject UUID. AxHub resolves that subject's active Hub email; verify the intended mailbox during rollout. A queued result means queue acceptance; recipient preferences can suppress email, and it does not establish delivery.
Set WORK_SLACK_ENABLED=1, WORK_SLACK_TEAM_ID, and WORK_SLACK_BOT_TOKEN_FILE for Slack DMs. The file must be an absolute server-owned regular file with mode 0600, containing a bot token with chat:write and im:write. The bot workspace is checked with auth.test; the current native organization's slackMemberId supplies the single DM recipient. No shared channel is inferred. The AxHub deployment wrapper materializes an injected WORK_SLACK_BOT_TOKEN into this file automatically.
Both channels default off. Enabled channels with missing configuration report unconfigured through authenticated /api/runtime; provider configuration failures report a safe error reason. Delivery counts are available only to native admins. Native Inbox continues to operate without external provider configuration.
The private durable outbox starts at the original journal sequence when a channel is enabled; old Inbox and late-projected preactivation events are skipped. Restart with the same configuration preserves pending work. Reenable or account/workspace changes establish a new floor. Destinations and resource/thread access are checked immediately before sending, including after opening a Slack DM. Messages contain a generic reason and an authenticated resource link, without copied ticket or comment content. Confirmed rate-limit rejections retry at most five times within 24 hours; ambiguous dispatches remain uncertain and are never automatically resent. Slack accepted confirms API acceptance, not that a person read the DM.
AxHub runtime integration secrets and connection checks
node scripts/start-axhub.mjs accepts platform-injected WORK_GITHUB_PRIVATE_KEY_PEM, WORK_GITHUB_WEBHOOK_SECRET, and WORK_SLACK_BOT_TOKEN. It validates and writes them before runtime configuration into unique server-owned 0700 temporary directories with exclusive regular 0600 files, then removes the raw environment values. Files are cleaned on startup failure and normal process exit. An abrupt process kill can leave the temporary files until the container is removed. Existing *_FILE settings remain supported; supplying both a raw secret and its file setting is an error. Never put real secrets into source or command-line arguments. GitHub stays disabled by default until a real dedicated App and its installation are configured.
An authenticated native administrator can POST /api/notifications/test with exactly {"channel":"email"} or {"channel":"slack"} from the app's allowed origin. The server sends the fixed APTA 알림 연결 확인 message and authenticated Inbox link only to that administrator's current bound Hub subject or native Slack member ID. No recipient, message, or user override is accepted, and automation Bearer tokens cannot use the endpoint. Active native membership and destination are checked again after opening the Slack DM.
A successful email check returns queued; Slack returns accepted, with only a provider message ID. Missing configuration/destination returns 409, a duplicate within 60 seconds or any concurrent check returns 429, and unknown provider outcomes return 503 with NOTIFICATION_TEST_UNCERTAIN. Tests have no automatic retry and create no normal Inbox/outbox rows. They establish provider connectivity, while actual event-to-Inbox audience behavior (including self-notification suppression) is verified separately.
SI·자사 프로젝트와 루피 AI
프로젝트는 /projects/si, /projects/own에서 구분하며, 상세 화면은 원본 e2e-local의 탭·사이드·카드 보기와 스프린트 목표·PBL·태스크·타임라인·데일리 스크럼·4L 회고를 제공합니다. 기존 /projects/:id 링크도 사용할 수 있습니다. 프로젝트 편집에서 스크럼·칸반·스크럼반을 선택하거나 질문으로 방법론을 추천받은 뒤 명시적으로 적용할 수 있습니다. SI에서 칸반을 선택하면 원본과 같이 스프린트 관리가 기본 해제됩니다. 스프린트 관리를 꺼도 기존 스프린트·업무·회고 데이터는 삭제되지 않습니다.
프로젝트 오른쪽 아래 루피를 열면 대화·제안·설정 탭과 브리핑을 사용할 수 있습니다. 루피는 업무 생성·수정안을 제안하고, 사용자가 변경 전후를 확인한 뒤 확정해야 반영합니다. 실제 반영은 기존 업무 서비스의 권한·워크플로·티켓 식별자·감사 이력 규칙을 따릅니다. 기존 4DX 맥락 안내도 유지됩니다.
AI는 기본 비활성입니다. 서버에 다음 환경 변수를 설정하고 재시작하면 활성화됩니다. 키와 모델 설정은 브라우저에 전달하지 않습니다.
WORK_AI_ENABLED=1
WORK_AI_PROVIDER=openai-responses
WORK_AI_BASE_URL=https://api.openai.com/v1
WORK_AI_API_KEY=<서버의 비밀 키>
WORK_AI_MODEL=<제공자가 지원하는 모델 ID>
WORK_AI_SCOPE=<워크스페이스별 고정 식별자>AXRouter Anthropic 전송을 사용하려면 WORK_AI_PROVIDER=axrouter-anthropic과 WORK_AI_BASE_URL=https://axrouter.ai/v1을 명시합니다. 원본 E2E_AI_* 환경 변수는 이 앱에서 사용하지 않습니다. AI에는 현재 접근 가능한 프로젝트 ID·이름·상태와 최대 100개 업무의 ID·제목·상태·우선순위·담당자 ID 및 입력한 대화만 전달합니다. 문서 본문·다른 프로젝트·인증 비밀은 포함하지 않습니다. 대화는 서버 메모리에서 최대 30분·10왕복 동안 유지되고, 사용량·제안 상태는 데이터베이스에 저장됩니다. 원본과 같은 일일 한도(사용자 20회, 워크스페이스 100회)와 동시 요청 제한을 적용합니다.
