leerness 1.31.0 → 1.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/catalogs.js CHANGED
@@ -3,22 +3,23 @@
3
3
  // 런타임 변형 없음 — capabilitiesCmd/adapterCmd/_reuseDetect/reuseCheckCmd 소비처 모두 읽기 전용.
4
4
  'use strict';
5
5
 
6
+ // 1.31.3 (UR-0010): desc/optOut/note 는 ko 기본 + *En 영어 변형 (capabilities --language en 렌더가 *En||원본 사용).
6
7
  const CAPABILITY_SURFACE = {
7
- filesystem: { risk: 'low', desc: '.harness/ 메타파일 생성·갱신, 변경 전 .harness/archive/ 자동 백업. 소스코드는 직접 수정 안 함.', optOut: '핵심 동작 (백업으로 보호)' },
8
- network: { risk: 'low', desc: 'npm 최신 버전 비교(update --check)만. 그 외 외부 URL 자동 fetch 안 함.', optOut: 'LEERNESS_OFFLINE=1' },
9
- childProcess: { risk: 'medium', desc: 'git(명시 명령 시 status/commit/push), npm test(verify-code), 외부 CLI --version 감지. 셸 spawn.', optOut: 'verify 계열 한정 · 외부 CLI 는 opt-in' },
10
- externalAgents: { risk: 'medium', desc: 'agents dispatch/multi — 외부 AI CLI(claude/codex/agy/grok/copilot) 호출. 기본은 명령 텍스트만 생성, multi --execute 시 실제 spawn.', optOut: 'LEERNESS_ENABLE_* 미설정 시 비활성 (기본 off)' },
11
- automationBridges: { risk: 'high', desc: 'web(playwright)/pc(robotjs)/lsp(typescript) 브리지 — opt-in 의존성. pc 는 마우스/키보드 제어(full 권한).', optOut: '의존성 미설치 시 비활성 (기본 off, 명시 설치 필요)' },
12
- claudeHook: { risk: 'low', desc: 'init 시 .claude/settings.local.json 에 SessionStart hook(update --check) 설치.', optOut: 'leerness init . --no-auto-update' }
8
+ filesystem: { risk: 'low', desc: '.harness/ 메타파일 생성·갱신, 변경 전 .harness/archive/ 자동 백업. 소스코드는 직접 수정 안 함.', descEn: 'Create/update .harness/ metadata files, auto-backup to .harness/archive/ before changes. Does not modify source code directly.', optOut: '핵심 동작 (백업으로 보호)', optOutEn: 'core behavior (protected by backups)' },
9
+ network: { risk: 'low', desc: 'npm 최신 버전 비교(update --check)만. 그 외 외부 URL 자동 fetch 안 함.', descEn: 'Only npm latest-version comparison (update --check). No other external URL is fetched automatically.', optOut: 'LEERNESS_OFFLINE=1', optOutEn: 'LEERNESS_OFFLINE=1' },
10
+ childProcess: { risk: 'medium', desc: 'git(명시 명령 시 status/commit/push), npm test(verify-code), 외부 CLI --version 감지. 셸 spawn.', descEn: 'git (status/commit/push on explicit commands), npm test (verify-code), external CLI --version detection. Shell spawn.', optOut: 'verify 계열 한정 · 외부 CLI 는 opt-in', optOutEn: 'limited to verify family · external CLIs are opt-in' },
11
+ externalAgents: { risk: 'medium', desc: 'agents dispatch/multi — 외부 AI CLI(claude/codex/agy/grok/copilot) 호출. 기본은 명령 텍스트만 생성, multi --execute 시 실제 spawn.', descEn: 'agents dispatch/multi — calls external AI CLIs (claude/codex/agy/grok/copilot). By default only generates command text; spawns for real on multi --execute.', optOut: 'LEERNESS_ENABLE_* 미설정 시 비활성 (기본 off)', optOutEn: 'disabled unless LEERNESS_ENABLE_* is set (off by default)' },
12
+ automationBridges: { risk: 'high', desc: 'web(playwright)/pc(robotjs)/lsp(typescript) 브리지 — opt-in 의존성. pc 는 마우스/키보드 제어(full 권한).', descEn: 'web(playwright)/pc(robotjs)/lsp(typescript) bridges — opt-in dependencies. pc controls mouse/keyboard (full access).', optOut: '의존성 미설치 시 비활성 (기본 off, 명시 설치 필요)', optOutEn: 'disabled when the dependency is not installed (off by default, explicit install required)' },
13
+ claudeHook: { risk: 'low', desc: 'init 시 .claude/settings.local.json 에 SessionStart hook(update --check) 설치.', descEn: 'On init, installs a SessionStart hook (update --check) into .claude/settings.local.json.', optOut: 'leerness init . --no-auto-update', optOutEn: 'leerness init . --no-auto-update' }
13
14
  };
14
15
  const POWERFUL_COMMANDS = [
15
- { cmd: 'init', note: '.harness/ 50+ 파일 + .claude hook 생성 (변경 전 백업)' },
16
- { cmd: 'update --yes', note: '자동 마이그레이션 — 메타파일 갱신' },
17
- { cmd: 'agents multi --execute', note: '외부 AI CLI 실제 spawn (병렬 실행)' },
18
- { cmd: 'release publish / sync-main', note: 'git push + npm publish + GitHub release' },
19
- { cmd: 'pc <click|type|...>', note: '마우스/키보드 제어 (robotjs, full 권한)' },
20
- { cmd: 'web <...>', note: '헤드리스 브라우저 자동화 (playwright)' },
21
- { cmd: 'setup-agents', note: '외부 CLI 활성화 + 자동 설치 시도' }
16
+ { cmd: 'init', note: '.harness/ 50+ 파일 + .claude hook 생성 (변경 전 백업)', noteEn: 'creates .harness/ 50+ files + .claude hook (backup before changes)' },
17
+ { cmd: 'update --yes', note: '자동 마이그레이션 — 메타파일 갱신', noteEn: 'auto migration — updates metadata files' },
18
+ { cmd: 'agents multi --execute', note: '외부 AI CLI 실제 spawn (병렬 실행)', noteEn: 'actually spawns external AI CLIs (parallel execution)' },
19
+ { cmd: 'release publish / sync-main', note: 'git push + npm publish + GitHub release', noteEn: 'git push + npm publish + GitHub release' },
20
+ { cmd: 'pc <click|type|...>', note: '마우스/키보드 제어 (robotjs, full 권한)', noteEn: 'mouse/keyboard control (robotjs, full access)' },
21
+ { cmd: 'web <...>', note: '헤드리스 브라우저 자동화 (playwright)', noteEn: 'headless browser automation (playwright)' },
22
+ { cmd: 'setup-agents', note: '외부 CLI 활성화 + 자동 설치 시도', noteEn: 'enables external CLIs + attempts auto-install' }
22
23
  ];
23
24
  const ADAPTERS = {
24
25
  claude: { label: 'Anthropic Claude Code', keys: ['CLAUDE.md', '.claude/commands/handoff.md', '.claude/commands/session-close.md', '.claude/commands/audit.md', '.claude/commands/lazy-detect.md', '.claude/commands/update.md', '.claude/skills/leerness.md'], mcp: true },
@@ -66,8 +67,8 @@ const _DEFAULT_PLATFORM_CONSTRAINTS = {
66
67
  docs: 'https://stripe.com/docs/rate-limits',
67
68
  constraints: [
68
69
  { kind: 'rate-limit', detail: 'read: 100 req/s, write: 100 req/s (live mode), test mode: 25 req/s' },
69
- { kind: 'idempotency', detail: 'Idempotency-Key 헤더 24h 유지 — 중복 결제 방지 필수' },
70
- { kind: 'webhook', detail: 'webhook 서명 검증 필수 (Stripe-Signature header + endpoint secret)' }
70
+ { kind: 'idempotency', detail: 'Idempotency-Key 헤더 24h 유지 — 중복 결제 방지 필수', detailEn: 'keep Idempotency-Key header for 24h — required to prevent duplicate charges' },
71
+ { kind: 'webhook', detail: 'webhook 서명 검증 필수 (Stripe-Signature header + endpoint secret)', detailEn: 'verify the webhook signature (Stripe-Signature header + endpoint secret) — required' }
71
72
  ]
72
73
  },
73
74
  openai: {
@@ -75,8 +76,8 @@ const _DEFAULT_PLATFORM_CONSTRAINTS = {
75
76
  docs: 'https://platform.openai.com/docs/guides/rate-limits',
76
77
  constraints: [
77
78
  { kind: 'rate-limit', detail: 'tier-based: Free 3 RPM / Tier 1 500 RPM / Tier 5 10,000 RPM' },
78
- { kind: 'token-limit', detail: 'TPM (tokens/min) 별도 — 큰 입력 시 RPM 도달 전 차단 가능' },
79
- { kind: 'cost', detail: 'gpt-4: $30/$60 per 1M input/output tokens — 대량 호출 전 비용 추정 필수' }
79
+ { kind: 'token-limit', detail: 'TPM (tokens/min) 별도 — 큰 입력 시 RPM 도달 전 차단 가능', detailEn: 'TPM (tokens/min) is separate — large inputs can hit it before RPM' },
80
+ { kind: 'cost', detail: 'gpt-4: $30/$60 per 1M input/output tokens — 대량 호출 전 비용 추정 필수', detailEn: 'gpt-4: $30/$60 per 1M input/output tokens — estimate cost before high volume' }
80
81
  ]
81
82
  },
82
83
  anthropic: {
@@ -84,7 +85,7 @@ const _DEFAULT_PLATFORM_CONSTRAINTS = {
84
85
  docs: 'https://docs.anthropic.com/claude/reference/rate-limits',
85
86
  constraints: [
86
87
  { kind: 'rate-limit', detail: 'tier-based: Free 5 RPM / Tier 1 50 RPM / Tier 4 4,000 RPM' },
87
- { kind: 'context-window', detail: 'claude-sonnet 200K context, claude-opus 200K, 1M tier 별도' },
88
+ { kind: 'context-window', detail: 'claude-sonnet 200K context, claude-opus 200K, 1M tier 별도', detailEn: 'claude-sonnet 200K context, claude-opus 200K, 1M tier separate' },
88
89
  { kind: 'cost', detail: 'sonnet: $3/$15 per 1M tokens (1M context tier 2x)' }
89
90
  ]
90
91
  },
@@ -94,15 +95,15 @@ const _DEFAULT_PLATFORM_CONSTRAINTS = {
94
95
  constraints: [
95
96
  { kind: 'rate-limit', detail: 'authenticated: 5,000 req/hr, unauthenticated: 60 req/hr' },
96
97
  { kind: 'rate-limit', detail: 'search API: 30 req/min (authenticated)' },
97
- { kind: 'secondary', detail: 'secondary rate limit — concurrent + content creation 별도 가드' }
98
+ { kind: 'secondary', detail: 'secondary rate limit — concurrent + content creation 별도 가드', detailEn: 'secondary rate limit — guard concurrent + content-creation separately' }
98
99
  ]
99
100
  },
100
101
  discord: {
101
102
  aliases: ['discord', 'discord api', 'discord bot'],
102
103
  docs: 'https://discord.com/developers/docs/topics/rate-limits',
103
104
  constraints: [
104
- { kind: 'rate-limit', detail: 'global: 50 req/s, per-route 별도' },
105
- { kind: 'invalid', detail: '10,000 invalid req/10min → 1h ban 위험' }
105
+ { kind: 'rate-limit', detail: 'global: 50 req/s, per-route 별도', detailEn: 'global: 50 req/s, per-route separate' },
106
+ { kind: 'invalid', detail: '10,000 invalid req/10min → 1h ban 위험', detailEn: '10,000 invalid req/10min → risk of a 1h ban' }
106
107
  ]
107
108
  },
108
109
  twitter: {
@@ -110,7 +111,7 @@ const _DEFAULT_PLATFORM_CONSTRAINTS = {
110
111
  docs: 'https://developer.twitter.com/en/docs/twitter-api/rate-limits',
111
112
  constraints: [
112
113
  { kind: 'rate-limit', detail: 'tier-based: Free 1,500 posts/month, Basic 50,000 posts/month' },
113
- { kind: 'auth', detail: 'OAuth 2.0 PKCE 필수 (user context), App-only는 별도 endpoint' }
114
+ { kind: 'auth', detail: 'OAuth 2.0 PKCE 필수 (user context), App-only는 별도 endpoint', detailEn: 'OAuth 2.0 PKCE required (user context); App-only uses a separate endpoint' }
114
115
  ]
115
116
  }
116
117
  }
package/lib/pure-utils.js CHANGED
@@ -462,7 +462,8 @@ function _parseSkillMd(text) {
462
462
  }
463
463
 
464
464
  // 1.9.333 (UR-0025 심층): 순수 플랫폼 제약 매칭 — catalog + 텍스트 → 매칭 플랫폼/제약/제안 (fs 의존 0, catalog 주입).
465
- function _matchConstraints(catalog, text) {
465
+ // 1.31.2 (UR-0010): optional lang ('en') → 영어 suggestion. 기본 'ko' (무회귀, selftest 2-arg 호출 보존).
466
+ function _matchConstraints(catalog, text, lang) {
466
467
  if (!text || typeof text !== 'string' || !catalog || !catalog.platforms) return { matched: [], suggestions: [] };
467
468
  const lower = text.toLowerCase();
468
469
  const matched = [];
@@ -474,7 +475,9 @@ function _matchConstraints(catalog, text) {
474
475
  const suggestions = [];
475
476
  const generic = /\bapi\b|연동|integration|호출|rate|limit|quota|webhook/i.test(text);
476
477
  if (generic && matched.length === 0) {
477
- suggestions.push('일반적 API 연동 키워드 감지 — leerness constraints list 로 사전 등록된 플랫폼 catalog 확인 권장');
478
+ suggestions.push(lang === 'en'
479
+ ? 'generic API-integration keywords detected — run leerness constraints list to review the pre-registered platform catalog'
480
+ : '일반적 API 연동 키워드 감지 — leerness constraints list 로 사전 등록된 플랫폼 catalog 확인 권장');
478
481
  }
479
482
  return { matched, suggestions, totalPlatforms: Object.keys(catalog.platforms).length };
480
483
  }
@@ -807,10 +810,18 @@ function _composeTeamPlan(team, task) {
807
810
  }
808
811
 
809
812
  // 1.9.373 (UR-0073 Phase C): 비-manual·active 팀의 handoff 스케줄 알림 라인 (순수). 실행 트리거 아님 — 미리보기 안내만.
810
- function _teamHandoffReminders(teams) {
813
+ // 1.31.3 (UR-0010): optional lang ('en') → 영어 라벨. 기본 'ko' (무회귀, 1-arg 호출 보존).
814
+ function _teamHandoffReminders(teams, lang) {
815
+ const en = lang === 'en';
811
816
  return (teams || [])
812
817
  .filter(t => t && t.schedule && t.schedule !== 'manual' && (t.status || 'active') === 'active' && t.id)
813
- .map(t => `🤝 ${t.id} (${t.schedule})${Array.isArray(t.members) && t.members.length ? ' · ' + t.members.length + '명' : ''}${t.review !== false ? ' · 검수필요' : ''} — 미리보기: leerness team preview ${t.id}`);
818
+ .map(t => {
819
+ const n = Array.isArray(t.members) ? t.members.length : 0;
820
+ const memberPart = n ? (en ? ` · ${n} member${n === 1 ? '' : 's'}` : ` · ${n}명`) : '';
821
+ const reviewPart = t.review !== false ? (en ? ' · review needed' : ' · 검수필요') : '';
822
+ const preview = en ? 'preview' : '미리보기';
823
+ return `🤝 ${t.id} (${t.schedule})${memberPart}${reviewPart} — ${preview}: leerness team preview ${t.id}`;
824
+ });
814
825
  }
815
826
 
816
827
  // 1.9.374 (UR-0074): 릴리스 케이던스 평가 (순수) — releases/day → 수준 + 권장. 외부리뷰 "릴리스 빈도 과다" 가시화.
package/package.json CHANGED
@@ -1,58 +1,58 @@
1
- {
2
- "name": "leerness",
3
- "version": "1.31.0",
4
- "description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
5
- "keywords": [
6
- "leerness",
7
- "ai",
8
- "agent",
9
- "harness",
10
- "context-engineering",
11
- "claude",
12
- "claude-code",
13
- "cursor",
14
- "copilot",
15
- "skill-library",
16
- "project-memory",
17
- "task-tracking",
18
- "planning",
19
- "handoff",
20
- "anti-laziness",
21
- "encoding",
22
- "secret-scan",
23
- "auto-update",
24
- "design-system",
25
- "developer-tools",
26
- "korean"
27
- ],
28
- "license": "MIT",
29
- "author": "leerness contributors",
30
- "type": "commonjs",
31
- "main": "bin/leerness.js",
32
- "preferGlobal": true,
33
- "engines": {
34
- "node": ">=18"
35
- },
36
- "bin": {
37
- "leerness": "bin/leerness.js"
38
- },
39
- "files": [
40
- "bin",
41
- "lib",
42
- "scripts",
43
- "docs",
44
- "README.md",
45
- "CHANGELOG.md",
46
- "SECURITY.md",
47
- "LICENSE"
48
- ],
49
- "scripts": {
50
- "test": "node ./bin/leerness.js --version && node ./bin/leerness.js selftest && node ./scripts/e2e.js",
51
- "test:fast": "node ./bin/leerness.js selftest && node ./scripts/smoke.js",
52
- "test:smoke": "node ./scripts/e2e.js",
53
- "prepack": "node ./bin/leerness.js readme sync . && node ./bin/leerness.js --version"
54
- },
55
- "publishConfig": {
56
- "access": "public"
57
- }
58
- }
1
+ {
2
+ "name": "leerness",
3
+ "version": "1.33.0",
4
+ "description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
5
+ "keywords": [
6
+ "leerness",
7
+ "ai",
8
+ "agent",
9
+ "harness",
10
+ "context-engineering",
11
+ "claude",
12
+ "claude-code",
13
+ "cursor",
14
+ "copilot",
15
+ "skill-library",
16
+ "project-memory",
17
+ "task-tracking",
18
+ "planning",
19
+ "handoff",
20
+ "anti-laziness",
21
+ "encoding",
22
+ "secret-scan",
23
+ "auto-update",
24
+ "design-system",
25
+ "developer-tools",
26
+ "korean"
27
+ ],
28
+ "license": "MIT",
29
+ "author": "leerness contributors",
30
+ "type": "commonjs",
31
+ "main": "bin/leerness.js",
32
+ "preferGlobal": true,
33
+ "engines": {
34
+ "node": ">=18"
35
+ },
36
+ "bin": {
37
+ "leerness": "bin/leerness.js"
38
+ },
39
+ "files": [
40
+ "bin",
41
+ "lib",
42
+ "scripts",
43
+ "docs",
44
+ "README.md",
45
+ "CHANGELOG.md",
46
+ "SECURITY.md",
47
+ "LICENSE"
48
+ ],
49
+ "scripts": {
50
+ "test": "node ./bin/leerness.js --version && node ./bin/leerness.js selftest && node ./scripts/e2e.js",
51
+ "test:fast": "node ./bin/leerness.js selftest && node ./scripts/smoke.js",
52
+ "test:smoke": "node ./scripts/e2e.js",
53
+ "prepack": "node ./bin/leerness.js readme sync . && node ./bin/leerness.js --version"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ }
58
+ }