@su-record/vibe 2.13.0 → 2.14.1

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.
Files changed (69) hide show
  1. package/CLAUDE.md +18 -15
  2. package/README.en.md +7 -5
  3. package/README.md +8 -6
  4. package/dist/cli/detect/matcher.d.ts +15 -0
  5. package/dist/cli/detect/matcher.d.ts.map +1 -0
  6. package/dist/cli/detect/matcher.js +278 -0
  7. package/dist/cli/detect/matcher.js.map +1 -0
  8. package/dist/cli/detect/signatures.d.ts +76 -0
  9. package/dist/cli/detect/signatures.d.ts.map +1 -0
  10. package/dist/cli/detect/signatures.js +175 -0
  11. package/dist/cli/detect/signatures.js.map +1 -0
  12. package/dist/cli/detect/workspace.d.ts +7 -0
  13. package/dist/cli/detect/workspace.d.ts.map +1 -0
  14. package/dist/cli/detect/workspace.js +112 -0
  15. package/dist/cli/detect/workspace.js.map +1 -0
  16. package/dist/cli/detect.characterization.test.d.ts +7 -0
  17. package/dist/cli/detect.characterization.test.d.ts.map +1 -0
  18. package/dist/cli/detect.characterization.test.js +294 -0
  19. package/dist/cli/detect.characterization.test.js.map +1 -0
  20. package/dist/cli/detect.d.ts.map +1 -1
  21. package/dist/cli/detect.js +64 -488
  22. package/dist/cli/detect.js.map +1 -1
  23. package/dist/cli/postinstall/constants.d.ts.map +1 -1
  24. package/dist/cli/postinstall/constants.js +1 -0
  25. package/dist/cli/postinstall/constants.js.map +1 -1
  26. package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
  27. package/dist/cli/setup/ProjectSetup.js +5 -4
  28. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  29. package/dist/infra/lib/ui-ux/CsvDataLoader.d.ts +10 -1
  30. package/dist/infra/lib/ui-ux/CsvDataLoader.d.ts.map +1 -1
  31. package/dist/infra/lib/ui-ux/CsvDataLoader.js +11 -5
  32. package/dist/infra/lib/ui-ux/CsvDataLoader.js.map +1 -1
  33. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js +8 -8
  34. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js.map +1 -1
  35. package/dist/infra/lib/ui-ux/SearchService.test.js +1 -1
  36. package/dist/infra/lib/ui-ux/SearchService.test.js.map +1 -1
  37. package/dist/tools/index.d.ts +2 -0
  38. package/dist/tools/index.d.ts.map +1 -1
  39. package/dist/tools/index.js +2 -0
  40. package/dist/tools/index.js.map +1 -1
  41. package/dist/tools/loop/index.d.ts +6 -0
  42. package/dist/tools/loop/index.d.ts.map +1 -0
  43. package/dist/tools/loop/index.js +5 -0
  44. package/dist/tools/loop/index.js.map +1 -0
  45. package/dist/tools/loop/validateLoopDefinition.d.ts +38 -0
  46. package/dist/tools/loop/validateLoopDefinition.d.ts.map +1 -0
  47. package/dist/tools/loop/validateLoopDefinition.js +224 -0
  48. package/dist/tools/loop/validateLoopDefinition.js.map +1 -0
  49. package/dist/tools/loop/validateLoopDefinition.test.d.ts +14 -0
  50. package/dist/tools/loop/validateLoopDefinition.test.d.ts.map +1 -0
  51. package/dist/tools/loop/validateLoopDefinition.test.js +229 -0
  52. package/dist/tools/loop/validateLoopDefinition.test.js.map +1 -0
  53. package/hooks/scripts/__tests__/.vibe/command-log.txt +39 -0
  54. package/hooks/scripts/__tests__/.vibe/memories/memories.db-shm +0 -0
  55. package/hooks/scripts/__tests__/.vibe/memories/memories.db-wal +0 -0
  56. package/hooks/scripts/__tests__/keyword-detector.test.js +26 -18
  57. package/hooks/scripts/__tests__/loop-ledger.test.js +321 -0
  58. package/hooks/scripts/keyword-detector.js +22 -22
  59. package/hooks/scripts/lib/hook-context.js +31 -2
  60. package/hooks/scripts/lib/loop-ledger.js +118 -0
  61. package/hooks/scripts/loop-ledger.js +56 -0
  62. package/package.json +3 -2
  63. package/skills/vibe/SKILL.md +40 -23
  64. package/skills/vibe.loop/SKILL.md +116 -0
  65. package/skills/vibe.run/SKILL.md +22 -18
  66. package/skills/vibe.run/references/ralph-loop.md +18 -17
  67. package/skills/vibe.run/references/ultrawork-mode.md +36 -33
  68. package/vibe/rules/loop-contract.md +54 -0
  69. package/vibe/templates/loop-template.md +69 -0
package/CLAUDE.md CHANGED
@@ -39,10 +39,10 @@ Function ≤50 lines · Nesting ≤3 · Params ≤5 · Cyclomatic ≤10
39
39
  No `console.log` in commits · No hardcoded strings/numbers · No commented-out code · No incomplete code without TODO
40
40
 
41
41
  ### Convergence (review / auto-fix loops)
42
- - **Loop until P1 = 0 AND no new findings** — no round cap; the model follows this protocol run/verify state is tracked in `.vibe/metrics/run-ledger.json`
42
+ Loop semantics SSOT: `vibe/rules/loop-contract.md` (ANCHOR→ACT→JUDGE→RECORD; exit = gates pass stuck max_iterations).
43
+ - **Loop until P1 = 0 AND no new findings** — run/verify state is tracked in `.vibe/metrics/run-ledger.json`; stuck is judged by discover-hash (2 identical rounds), not by the model
43
44
  - **Narrowing scope**: Round 1 full → Round 2 P1+P2 → Round 3+ P1 only
44
- - **Stuck detection** (same findings/score 2 rounds in a row) → ask user (fill values / approve sub-100 / abort). Never silently proceed sub-100
45
- - **`ultrawork` exception** — skip user prompt; record gaps as TODO to stay non-interactive
45
+ - **Stuck** → ask user (fill values / approve sub-100 / abort); `automationLevel: autonomous` records a TODO and continues non-interactively. Never silently proceed sub-100
46
46
  - **Changed files only** — never full-project scan
47
47
 
48
48
  ## Architecture (Non-Obvious)
@@ -85,15 +85,15 @@ Legacy: 기존 `.claude/vibe/` 는 런타임에 자동 인식되며 `vibe init`/
85
85
 
86
86
  ## Workflow
87
87
 
88
- Claude Code uses `/vibe` as the **single slash entry point**. Codex exposes the same Vibe entrypoints as skills, so use `$vibe`, `$vibe.spec`, or `/skills` instead of expecting top-level `/vibe.*` slash commands in the Codex popup. Natural-language requirement (+ optional URL/image/PDF/file attachments) → vibe analyzes intent, designs a pipeline of `vibe.*` skills, shows a preview, gets one approval, then chains them. `ultrawork` keyword skips the approval gate.
88
+ Claude Code uses `/vibe` as the **single slash entry point**. Codex exposes the same Vibe entrypoints as skills, so use `$vibe`, `$vibe.spec`, or `/skills` instead of expecting top-level `/vibe.*` slash commands in the Codex popup. Natural-language requirement (+ optional URL/image/PDF/file attachments) → vibe analyzes intent, confirms the SPEC once (the only mandatory human gate), then loops per `vibe/rules/loop-contract.md` until gates pass. `automationLevel: autonomous` skips the confirmation for non-interactive runs.
89
89
 
90
90
  ```
91
91
  $vibe "<requirement>" [+ 📎 attachments] # Codex
92
92
  /vibe "<requirement>" [+ 📎 attachments] # Claude Code
93
93
  → Intent classification (new feature / figma-driven / clone / resume / review / regress / contract / scaffold / docs / analyze / harness / test / utils)
94
94
  → Smart Resume detection (.vibe/{interviews,plans,specs,features}/)
95
- Pipeline preview + 1-time approval (skipped on `ultrawork`)
96
- Sequential SlashCommand chain
95
+ SPEC confirmation (1-time approval; skipped on automationLevel: autonomous)
96
+ Loop: ANCHOR→ACT→JUDGE→RECORD until gates pass │ stuck │ max-iter
97
97
  ```
98
98
 
99
99
  **Advanced (explicit phase) entrypoints** — still available for power users when you know exactly which phase to run:
@@ -104,6 +104,7 @@ $vibe "<requirement>" [+ 📎 attachments] # Codex
104
104
  - Codex: `$vibe.regress` / Claude Code: `/vibe.regress` — regression test auto-evolution. Auto-registers on verify failure; `generate` produces preventive tests; `cluster` promotes recurring patterns.
105
105
  - Codex: `$vibe.contract` / Claude Code: `/vibe.contract` — API contract drift detection. Compares the contract extracted from the SPEC against the implementation; P1 drift auto-propagates to regress.
106
106
  - Codex: `$vibe.trace` / Claude Code: `/vibe.trace` — Requirements Traceability Matrix
107
+ - Codex: `$vibe.loop` / Claude Code: `/vibe.loop` — loop engineering. Goal loops whose completion is judged by deterministic gates (run-ledger/tests), with stuck detection by discover-hash and a human triage inbox. Loops never push/release.
107
108
  - Codex: `$vibe.test` / Claude Code: `/vibe.test` — vibe self-test across the CC ↔ Codex harnesses. Subcommands: `parity` (static), `report` (runtime), `compare` (diff). P1 drift auto-propagates to regress. Recommended before every release.
108
109
 
109
110
  | Task Size | Approach |
@@ -111,15 +112,17 @@ $vibe "<requirement>" [+ 📎 attachments] # Codex
111
112
  | 1–2 files | Plan Mode |
112
113
  | 3+ files | `$vibe "<requirement>"` in Codex, `/vibe "<requirement>"` in Claude Code (or the explicit `vibe.spec` entrypoint) |
113
114
 
114
- ## Magic Keywords
115
+ ## Loop Contract (default execution model)
115
116
 
116
- | Keyword | Effect |
117
- |---|---|
118
- | `ultrawork` / `ulw` | Parallel agents + auto-continue + Ralph Loop |
119
- | `ralph` | Iterate to 100% (no scope reduction) |
120
- | `ralplan` | Iterative planning + persistence |
121
- | `verify` | Strict verification mode |
122
- | `quick` | Fast mode, minimal verification |
117
+ `/vibe {requirement}` = SPEC approval once (the only mandatory human gate) → loop ANCHOR→ACT→JUDGE→RECORD until gates pass. Completion is judged by deterministic gates (run-ledger `verifyPassed`, test exit codes), never by self-report. SSOT: `vibe/rules/loop-contract.md`.
118
+
119
+ | Parameter | Default | Meaning |
120
+ |---|---|---|
121
+ | `--interactive` | off | Per-step confirmation (the old default) |
122
+ | `--max-iter N` | 10 | Iteration cap |
123
+ | `automationLevel` | `confirm` | `confirm` / `autonomous` (non-interactive; stuck → TODO) — `.vibe/config.json` |
124
+
125
+ **Deprecated aliases** (mapped, not taught): `ralph`→default(no-op) · `verify`→default(no-op) · `quick`→`--max-iter 1` · `ralplan`→loop applied to planning · `ultrawork`/`ulw`→`automationLevel: autonomous` + parallel ACT
123
126
 
124
127
  ## Skill Tiers
125
128
 
@@ -132,7 +135,7 @@ $vibe "<requirement>" [+ 📎 attachments] # Codex
132
135
 
133
136
  ## Git
134
137
 
135
- **Include**: `.vibe/{plans,specs,features,todos,research,regressions,contracts,recipes,anti-patterns,config.json,constitution.md}`, `CLAUDE.md`
138
+ **Include**: `.vibe/{plans,specs,features,todos,research,regressions,contracts,recipes,anti-patterns,loops,config.json,constitution.md}`, `CLAUDE.md`
136
139
  **Vibe-global (not project-local)**: `~/.vibe/test-reports/` — `/vibe.test` artifacts live with the vibe install, not with the project
137
140
  **Exclude**: `~/.claude/{rules,commands,agents,skills}/`, `.claude/settings.local.json`, `.vibe/{memories,checkpoints,metrics}/`
138
141
 
package/README.en.md CHANGED
@@ -32,15 +32,17 @@ One entry point. Everything else is automatic.
32
32
  Pipeline design ─── /vibe.spec → /vibe.figma → /vibe.run → /vibe.verify → /vibe.trace
33
33
  |
34
34
  v
35
- One approval gate (skipped with ultrawork)
35
+ SPEC approval once ─── the only mandatory human gate (defines Done)
36
36
  |
37
37
  v
38
- Sequential execution ─── each phase hands off to the next
38
+ Loop ─── ANCHOR→ACT→JUDGE→RECORD until gates pass (stuck/iteration guards)
39
39
  ```
40
40
 
41
41
  **Smart Resume** — Stop at any step, close the session, come back later. `/vibe` auto-detects where you left off and picks up from there. No need to remember feature names.
42
42
 
43
- **ultrawork** — Add `ultrawork` to skip all confirmation gates and run the full pipeline hands-free.
43
+ **Loop-default** — After SPEC approval, vibe loops (ANCHOR→ACT→JUDGE→RECORD) until gates pass, with deterministic stuck/iteration guards. `--interactive` for step-by-step confirmation; `--max-iter N` to cap iterations. `ultrawork` is a deprecated alias for `automationLevel: autonomous` + parallel ACT.
44
+
45
+ **Loop engineering** — `/vibe.loop` designs and installs autonomous goal loops (triage → run/verify pipelines). Completion is judged by deterministic gates (run-ledger/tests), not self-report; results land in a human triage inbox — loops never push or release.
44
46
 
45
47
  ---
46
48
 
@@ -168,9 +170,9 @@ Detection at edit time, blocking at deterministic gates — three layers of defe
168
170
 
169
171
  ## Key Features
170
172
 
171
- **40+ agents** — Exploration, implementation, architecture, parallel code review, UI/UX analysis, security audit, Figma analysis/building. The UI/Figma/Event groups (18 agents) are excluded from the global install — `vibe init` installs them project-locally (`.claude/agents/`) only when the stack/capability matches, so they never occupy context in unrelated projects.
173
+ **42+ agents** — Exploration, implementation, architecture, parallel code review, UI/UX analysis, security audit, Figma analysis/building. The UI/Figma/Event groups (18 agents) are excluded from the global install — `vibe init` installs them project-locally (`.claude/agents/`) only when the stack/capability matches, so they never occupy context in unrelated projects.
172
174
 
173
- **44 skills** — Not all loaded at once. 3-tier system prevents context overload:
175
+ **70 skills** — Not all loaded at once. 3-tier system prevents context overload:
174
176
 
175
177
  | Tier | When loaded | Purpose | Examples |
176
178
  |------|-------------|---------|----------|
package/README.md CHANGED
@@ -35,10 +35,10 @@ vibe init
35
35
  파이프라인 설계 ─── /vibe.spec → /vibe.figma → /vibe.run → /vibe.verify → /vibe.trace
36
36
  |
37
37
  v
38
- 1회 승인 게이트 (ultrawork 키워드 있으면 skip)
38
+ SPEC 확정 1회 승인 ─── 유일한 의무 개입 (Done의 정의 확정)
39
39
  |
40
40
  v
41
- 순차 실행 ─── phase 완료 다음으로
41
+ 루프 ─── ANCHOR→ACT→JUDGE→RECORD (게이트 통과까지 자동 반복)
42
42
  ```
43
43
 
44
44
  **예시:**
@@ -48,12 +48,12 @@ vibe init
48
48
  /vibe "https://figma.com/file/abc 로 로그인 페이지"
49
49
  /vibe "로그인 회귀 테스트 다시 통과시켜줘"
50
50
  /vibe "이 SPEC 리뷰만" + 📎 .vibe/specs/login.md
51
- /vibe "결제 API" ultrawork # 승인 게이트 skip
51
+ /vibe "결제 API" ultrawork # automationLevel: autonomous (deprecated alias)
52
52
  ```
53
53
 
54
54
  **Smart Resume** — 아무 단계에서나 멈추고 나중에 돌아오세요. `/vibe`는 `.vibe/` 디렉토리에서 진행 상황을 감지하고 "이어서?" 제안합니다.
55
55
 
56
- **ultrawork** — `ultrawork` 키워드를 붙이면 승인 게이트와 모든 중단점을 skip하고 자동 실행합니다.
56
+ **루프 기본 실행** SPEC 확정 1회 승인 후 게이트 통과까지 자동 루프합니다. `--interactive`로 단계별 확인 모드, `--max-iter N`으로 반복 상한 설정. `ultrawork`는 `automationLevel: autonomous` + 병렬 실행의 deprecated 별칭으로 동작합니다.
57
57
 
58
58
  **Advanced** — 정확히 어느 phase 실행할지 알면 `/vibe.spec`, `/vibe.figma`, `/vibe.run`, `/vibe.verify`, `/vibe.trace` 등을 직접 호출할 수 있습니다.
59
59
 
@@ -142,9 +142,9 @@ codex
142
142
 
143
143
  ## 주요 기능
144
144
 
145
- **40+ 에이전트** — 탐색, 구현, 아키텍처, 병렬 코드 리뷰, UI/UX 분석, 보안 감사, Figma 분석/빌드. UI·Figma·Event 그룹(18개)은 전역 설치에서 제외되고, `vibe init`이 스택/capability가 맞는 프로젝트에만 로컬(`.claude/agents/`)로 설치 — 비해당 프로젝트의 컨텍스트를 점유하지 않습니다.
145
+ **42+ 에이전트** — 탐색, 구현, 아키텍처, 병렬 코드 리뷰, UI/UX 분석, 보안 감사, Figma 분석/빌드. UI·Figma·Event 그룹(18개)은 전역 설치에서 제외되고, `vibe init`이 스택/capability가 맞는 프로젝트에만 로컬(`.claude/agents/`)로 설치 — 비해당 프로젝트의 컨텍스트를 점유하지 않습니다.
146
146
 
147
- **44개 스킬** — 한 번에 다 로드되지 않음. 3-tier 시스템으로 컨텍스트 과부하 방지:
147
+ **70개 스킬** — 한 번에 다 로드되지 않음. 3-tier 시스템으로 컨텍스트 과부하 방지:
148
148
 
149
149
  | 티어 | 로드 시점 | 용도 | 예시 |
150
150
  |------|----------|------|------|
@@ -160,6 +160,8 @@ codex
160
160
 
161
161
  **Smart Resume** — `.last-feature` 포인터가 마지막 작업을 추적. 인자 없이 `/vibe`를 호출하면 중단된 위치를 보여주거나 진행 중 feature 목록을 제시.
162
162
 
163
+ **루프 엔지니어링** — `/vibe.loop`로 자율 목표 루프를 설계·설치(트리아지 → run/verify 파이프라인). 완료 판정은 자기 보고가 아니라 결정론 게이트(run-ledger/테스트)가 내리고, 결과는 사람 리뷰 인박스로 — 루프는 push/release를 하지 않습니다.
164
+
163
165
  ---
164
166
 
165
167
  ## 지원 도구
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Generic matchers that walk the signature tables to produce detection results.
3
+ * Each function is ≤50 lines and cyclomatic ≤10.
4
+ */
5
+ import type { DetectedStack, StackDetails } from '../types.js';
6
+ /**
7
+ * Detect all stacks and collect detail signals from a single directory.
8
+ * Returns detected stacks (may be empty).
9
+ */
10
+ export declare function detectInDir(dir: string, prefix: string, details: StackDetails): DetectedStack[];
11
+ /** Detect hosting providers from the project root. */
12
+ export declare function detectHosting(projectRoot: string): string[];
13
+ /** Detect CI/CD tools from the project root. */
14
+ export declare function detectCicd(projectRoot: string): string[];
15
+ //# sourceMappingURL=matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../../../src/cli/detect/matcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyQ/D;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa,EAAE,CAkC/F;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAI3D;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAIxD"}
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Generic matchers that walk the signature tables to produce detection results.
3
+ * Each function is ≤50 lines and cyclomatic ≤10.
4
+ */
5
+ import path from 'path';
6
+ import fs from 'fs';
7
+ import { NODE_STACK_SIGNATURES, PYTHON_STACK_SIGNATURES, FILE_MANIFEST_STACKS, GRADLE_STACK_SIGNATURES, MAVEN_STACK_SIGNATURES, SWIFT_STACK_SIGNATURES, RUBY_STACK_SIGNATURES, CSHARP_STACK_SIGNATURES, GODOT_STACK_SIGNATURES, DATABASE_SIGNATURES, STATE_MANAGEMENT_SIGNATURES, CAPABILITY_SIGNATURES, HOSTING_SIGNATURES, CICD_SIGNATURES, } from './signatures.js';
8
+ // ── internal helpers ───────────────────────────────────────────────────────
9
+ function readText(filePath) {
10
+ try {
11
+ return fs.readFileSync(filePath, 'utf-8');
12
+ }
13
+ catch {
14
+ return '';
15
+ }
16
+ }
17
+ function readPkg(dir) {
18
+ try {
19
+ const raw = JSON.parse(readText(path.join(dir, 'package.json')));
20
+ return { ...raw.dependencies, ...raw.devDependencies };
21
+ }
22
+ catch {
23
+ return {};
24
+ }
25
+ }
26
+ function hasPkg(dir) {
27
+ const raw = readText(path.join(dir, 'package.json'));
28
+ if (!raw)
29
+ return false;
30
+ try {
31
+ const p = JSON.parse(raw);
32
+ return typeof p.name === 'string';
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ function depsMatch(deps, keys) {
39
+ return keys.some(k => k in deps);
40
+ }
41
+ function contentMatch(text, needles) {
42
+ if (needles.length === 0)
43
+ return true; // empty = always matches (fallback)
44
+ return needles.some(n => text.includes(n));
45
+ }
46
+ // ── stack matchers ─────────────────────────────────────────────────────────
47
+ /** Match Node/TS stacks from package.json deps (first-match wins). */
48
+ function matchNodeStack(dir, prefix) {
49
+ if (!fs.existsSync(path.join(dir, 'package.json')))
50
+ return null;
51
+ const deps = readPkg(dir);
52
+ for (const sig of NODE_STACK_SIGNATURES) {
53
+ if (sig.packageDeps && depsMatch(deps, sig.packageDeps)) {
54
+ return { type: sig.type, path: prefix };
55
+ }
56
+ }
57
+ // fallback: plain package.json with a name
58
+ if (hasPkg(dir))
59
+ return { type: 'typescript-node', path: prefix };
60
+ return null;
61
+ }
62
+ /** Match Python stacks from pyproject.toml or requirements.txt (first-match wins). */
63
+ function matchPythonStack(dir, prefix) {
64
+ const pyproject = path.join(dir, 'pyproject.toml');
65
+ const requirements = path.join(dir, 'requirements.txt');
66
+ const manifestPath = fs.existsSync(pyproject) ? pyproject
67
+ : fs.existsSync(requirements) ? requirements
68
+ : null;
69
+ if (!manifestPath)
70
+ return null;
71
+ const text = readText(manifestPath);
72
+ for (const sig of PYTHON_STACK_SIGNATURES) {
73
+ if (contentMatch(text, sig.contentIncludes ?? [])) {
74
+ return { type: sig.type, path: prefix };
75
+ }
76
+ }
77
+ return null;
78
+ }
79
+ /** Match stacks that have a single manifest file (Flutter, Go, Rust). */
80
+ function matchFileManifestStacks(dir, prefix) {
81
+ return FILE_MANIFEST_STACKS
82
+ .filter(sig => sig.manifestFile && fs.existsSync(path.join(dir, sig.manifestFile)))
83
+ .map(sig => ({ type: sig.type, path: prefix }));
84
+ }
85
+ /** Match Gradle-based JVM stacks (first-match wins). */
86
+ function matchGradleStack(dir, prefix) {
87
+ const kts = path.join(dir, 'build.gradle.kts');
88
+ const groovy = path.join(dir, 'build.gradle');
89
+ const gradlePath = fs.existsSync(kts) ? kts : fs.existsSync(groovy) ? groovy : null;
90
+ if (!gradlePath)
91
+ return null;
92
+ const text = readText(gradlePath);
93
+ for (const sig of GRADLE_STACK_SIGNATURES) {
94
+ if (contentMatch(text, sig.contentIncludes ?? [])) {
95
+ return { type: sig.type, path: prefix };
96
+ }
97
+ }
98
+ return null;
99
+ }
100
+ /** Match Maven-based JVM stacks (first-match wins). */
101
+ function matchMavenStack(dir, prefix) {
102
+ if (!fs.existsSync(path.join(dir, 'pom.xml')))
103
+ return null;
104
+ const text = readText(path.join(dir, 'pom.xml'));
105
+ for (const sig of MAVEN_STACK_SIGNATURES) {
106
+ if (contentMatch(text, sig.contentIncludes ?? [])) {
107
+ return { type: sig.type, path: prefix };
108
+ }
109
+ }
110
+ return null;
111
+ }
112
+ /** Match predicate-based stacks (Swift, C#/Unity, Godot, Ruby). */
113
+ function matchPredicateStacks(dir, prefix, signatures) {
114
+ return signatures
115
+ .filter(sig => sig.predicate ? sig.predicate(dir, readPkg(dir)) : false)
116
+ .map(sig => ({ type: sig.type, path: prefix }));
117
+ }
118
+ /** Match Ruby/Rails stack. */
119
+ function matchRubyStack(dir, prefix) {
120
+ const gemfile = path.join(dir, 'Gemfile');
121
+ if (!fs.existsSync(gemfile))
122
+ return null;
123
+ const text = readText(gemfile);
124
+ for (const sig of RUBY_STACK_SIGNATURES) {
125
+ if (contentMatch(text, sig.contentIncludes ?? [])) {
126
+ return { type: sig.type, path: prefix };
127
+ }
128
+ }
129
+ return null;
130
+ }
131
+ // ── detail matchers ────────────────────────────────────────────────────────
132
+ function matchDatabasesFromDeps(deps, sigs) {
133
+ return sigs
134
+ .filter(s => s.packageDeps && depsMatch(deps, s.packageDeps))
135
+ .map(s => s.name);
136
+ }
137
+ function matchDatabasesFromContent(text, sigs) {
138
+ return sigs
139
+ .filter(s => s.contentIncludes && s.contentIncludes.length > 0 && contentMatch(text, s.contentIncludes))
140
+ .map(s => s.name);
141
+ }
142
+ function matchStateFromDeps(deps, sigs) {
143
+ return sigs
144
+ .filter(s => s.packageDeps && depsMatch(deps, s.packageDeps))
145
+ .map(s => s.name);
146
+ }
147
+ function matchStateFromContent(text, sigs) {
148
+ return sigs
149
+ .filter(s => s.contentIncludes && s.contentIncludes.length > 0 && contentMatch(text, s.contentIncludes))
150
+ .map(s => s.name);
151
+ }
152
+ function hasEventAutomationDir(dir, sig) {
153
+ if (!sig.requiresDirs)
154
+ return true;
155
+ return sig.requiresDirs.some(d => fs.existsSync(path.join(dir, d)));
156
+ }
157
+ function matchCapabilitiesFromDeps(dir, deps, sigs) {
158
+ return sigs
159
+ .filter(s => s.packageDeps && depsMatch(deps, s.packageDeps) && hasEventAutomationDir(dir, s))
160
+ .map(s => s.capability);
161
+ }
162
+ function matchCapabilitiesFromContent(dir, text, sigs) {
163
+ return sigs
164
+ .filter(s => s.contentIncludes &&
165
+ s.contentIncludes.length > 0 &&
166
+ contentMatch(text, s.contentIncludes) &&
167
+ hasEventAutomationDir(dir, s))
168
+ .map(s => s.capability);
169
+ }
170
+ // ── per-directory detail collection ───────────────────────────────────────
171
+ function collectNodeDetails(dir, details) {
172
+ if (!fs.existsSync(path.join(dir, 'package.json')))
173
+ return;
174
+ const deps = readPkg(dir);
175
+ details.databases.push(...matchDatabasesFromDeps(deps, DATABASE_SIGNATURES));
176
+ details.stateManagement.push(...matchStateFromDeps(deps, STATE_MANAGEMENT_SIGNATURES));
177
+ details.capabilities.push(...matchCapabilitiesFromDeps(dir, deps, CAPABILITY_SIGNATURES));
178
+ }
179
+ function collectPythonDetails(dir, details) {
180
+ const pyproject = path.join(dir, 'pyproject.toml');
181
+ const requirements = path.join(dir, 'requirements.txt');
182
+ const filePath = fs.existsSync(pyproject) ? pyproject
183
+ : fs.existsSync(requirements) ? requirements
184
+ : null;
185
+ if (!filePath)
186
+ return;
187
+ const text = readText(filePath);
188
+ details.databases.push(...matchDatabasesFromContent(text, DATABASE_SIGNATURES));
189
+ details.capabilities.push(...matchCapabilitiesFromContent(dir, text, CAPABILITY_SIGNATURES));
190
+ }
191
+ function collectFlutterDetails(dir, details) {
192
+ if (!fs.existsSync(path.join(dir, 'pubspec.yaml')))
193
+ return;
194
+ const text = readText(path.join(dir, 'pubspec.yaml'));
195
+ details.stateManagement.push(...matchStateFromContent(text, STATE_MANAGEMENT_SIGNATURES));
196
+ }
197
+ function collectGoDetails(dir, details) {
198
+ if (!fs.existsSync(path.join(dir, 'go.mod')))
199
+ return;
200
+ const text = readText(path.join(dir, 'go.mod'));
201
+ details.databases.push(...matchDatabasesFromContent(text, DATABASE_SIGNATURES));
202
+ }
203
+ function collectRustDetails(dir, details) {
204
+ if (!fs.existsSync(path.join(dir, 'Cargo.toml')))
205
+ return;
206
+ const text = readText(path.join(dir, 'Cargo.toml'));
207
+ details.databases.push(...matchDatabasesFromContent(text, DATABASE_SIGNATURES));
208
+ }
209
+ function collectGradleDetails(dir, details) {
210
+ const kts = path.join(dir, 'build.gradle.kts');
211
+ const groovy = path.join(dir, 'build.gradle');
212
+ const gradlePath = fs.existsSync(kts) ? kts : fs.existsSync(groovy) ? groovy : null;
213
+ if (!gradlePath)
214
+ return;
215
+ const text = readText(gradlePath);
216
+ details.databases.push(...matchDatabasesFromContent(text, DATABASE_SIGNATURES));
217
+ }
218
+ function collectMavenDetails(dir, details) {
219
+ if (!fs.existsSync(path.join(dir, 'pom.xml')))
220
+ return;
221
+ const text = readText(path.join(dir, 'pom.xml'));
222
+ details.databases.push(...matchDatabasesFromContent(text, DATABASE_SIGNATURES));
223
+ }
224
+ function collectRubyDetails(dir, details) {
225
+ if (!fs.existsSync(path.join(dir, 'Gemfile')))
226
+ return;
227
+ const text = readText(path.join(dir, 'Gemfile'));
228
+ details.databases.push(...matchDatabasesFromContent(text, DATABASE_SIGNATURES));
229
+ }
230
+ // ── public API ─────────────────────────────────────────────────────────────
231
+ /**
232
+ * Detect all stacks and collect detail signals from a single directory.
233
+ * Returns detected stacks (may be empty).
234
+ */
235
+ export function detectInDir(dir, prefix, details) {
236
+ const stacks = [];
237
+ const nodeStack = matchNodeStack(dir, prefix);
238
+ if (nodeStack)
239
+ stacks.push(nodeStack);
240
+ const pythonStack = matchPythonStack(dir, prefix);
241
+ if (pythonStack)
242
+ stacks.push(pythonStack);
243
+ stacks.push(...matchFileManifestStacks(dir, prefix));
244
+ const gradleStack = matchGradleStack(dir, prefix);
245
+ if (gradleStack)
246
+ stacks.push(gradleStack);
247
+ const mavenStack = matchMavenStack(dir, prefix);
248
+ if (mavenStack)
249
+ stacks.push(mavenStack);
250
+ const rubyStack = matchRubyStack(dir, prefix);
251
+ if (rubyStack)
252
+ stacks.push(rubyStack);
253
+ stacks.push(...matchPredicateStacks(dir, prefix, SWIFT_STACK_SIGNATURES));
254
+ stacks.push(...matchPredicateStacks(dir, prefix, CSHARP_STACK_SIGNATURES));
255
+ stacks.push(...matchPredicateStacks(dir, prefix, GODOT_STACK_SIGNATURES));
256
+ collectNodeDetails(dir, details);
257
+ collectPythonDetails(dir, details);
258
+ collectFlutterDetails(dir, details);
259
+ collectGoDetails(dir, details);
260
+ collectRustDetails(dir, details);
261
+ collectGradleDetails(dir, details);
262
+ collectMavenDetails(dir, details);
263
+ collectRubyDetails(dir, details);
264
+ return stacks;
265
+ }
266
+ /** Detect hosting providers from the project root. */
267
+ export function detectHosting(projectRoot) {
268
+ return HOSTING_SIGNATURES
269
+ .filter(sig => sig.files.some(f => fs.existsSync(path.join(projectRoot, f))))
270
+ .map(sig => sig.name);
271
+ }
272
+ /** Detect CI/CD tools from the project root. */
273
+ export function detectCicd(projectRoot) {
274
+ return CICD_SIGNATURES
275
+ .filter(sig => sig.files.some(f => fs.existsSync(path.join(projectRoot, f))))
276
+ .map(sig => sig.name);
277
+ }
278
+ //# sourceMappingURL=matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../../src/cli/detect/matcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Declarative stack-detection signature table.
3
+ * Each entry describes what files/deps/content to look for, and what to emit.
4
+ */
5
+ export interface StackSignature {
6
+ /** Unique stack identifier matched against STACK_NAMES */
7
+ type: string;
8
+ /**
9
+ * If provided, the signature is only considered when the given manifest file
10
+ * exists in the target directory.
11
+ */
12
+ manifestFile?: string;
13
+ /**
14
+ * For package.json-based stacks: list of dep keys (any match triggers).
15
+ * Checked against `{ ...dependencies, ...devDependencies }`.
16
+ */
17
+ packageDeps?: string[];
18
+ /**
19
+ * For text-based manifests (requirements.txt, pyproject.toml, go.mod, …):
20
+ * list of substrings. Any one match triggers.
21
+ */
22
+ contentIncludes?: string[];
23
+ /**
24
+ * Optional custom predicate — runs after file existence/dep/content checks.
25
+ * Receives the directory and (for package.json stacks) the merged deps object.
26
+ * Return true to confirm detection.
27
+ */
28
+ predicate?: (dir: string, deps: Record<string, string>) => boolean;
29
+ }
30
+ export interface CapabilitySignature {
31
+ capability: string;
32
+ /** package.json dep keys — any match */
33
+ packageDeps?: string[];
34
+ /** Content substrings for non-JS manifests — any match */
35
+ contentIncludes?: string[];
36
+ /** Optional extra guard — all of deps/content must also match */
37
+ requiresDirs?: string[];
38
+ }
39
+ export interface DatabaseSignature {
40
+ name: string;
41
+ packageDeps?: string[];
42
+ contentIncludes?: string[];
43
+ }
44
+ export interface StateManagementSignature {
45
+ name: string;
46
+ packageDeps?: string[];
47
+ contentIncludes?: string[];
48
+ }
49
+ export declare const NODE_STACK_SIGNATURES: StackSignature[];
50
+ export declare const PYTHON_STACK_SIGNATURES: StackSignature[];
51
+ /** Single-file manifests that map 1-to-1 to a stack type */
52
+ export declare const FILE_MANIFEST_STACKS: StackSignature[];
53
+ /** Gradle-based JVM stacks */
54
+ export declare const GRADLE_STACK_SIGNATURES: StackSignature[];
55
+ /** Maven pom.xml stacks */
56
+ export declare const MAVEN_STACK_SIGNATURES: StackSignature[];
57
+ /** Swift/iOS — requires Package.swift OR Xcode project files */
58
+ export declare const SWIFT_STACK_SIGNATURES: StackSignature[];
59
+ /** Ruby — Gemfile with "rails" keyword */
60
+ export declare const RUBY_STACK_SIGNATURES: StackSignature[];
61
+ /** C# / Unity — requires .csproj/.sln AND Unity-specific indicators */
62
+ export declare const CSHARP_STACK_SIGNATURES: StackSignature[];
63
+ /** GDScript / Godot */
64
+ export declare const GODOT_STACK_SIGNATURES: StackSignature[];
65
+ export declare const DATABASE_SIGNATURES: DatabaseSignature[];
66
+ export declare const STATE_MANAGEMENT_SIGNATURES: StateManagementSignature[];
67
+ export declare const CAPABILITY_SIGNATURES: CapabilitySignature[];
68
+ export declare const HOSTING_SIGNATURES: Array<{
69
+ name: string;
70
+ files: string[];
71
+ }>;
72
+ export declare const CICD_SIGNATURES: Array<{
73
+ name: string;
74
+ files: string[];
75
+ }>;
76
+ //# sourceMappingURL=signatures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../../src/cli/detect/signatures.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC;CACpE;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAyBD,eAAO,MAAM,qBAAqB,EAAE,cAAc,EAiBjD,CAAC;AAIF,eAAO,MAAM,uBAAuB,EAAE,cAAc,EAInD,CAAC;AAIF,4DAA4D;AAC5D,eAAO,MAAM,oBAAoB,EAAE,cAAc,EAIhD,CAAC;AAEF,8BAA8B;AAC9B,eAAO,MAAM,uBAAuB,EAAE,cAAc,EAKnD,CAAC;AAEF,2BAA2B;AAC3B,eAAO,MAAM,sBAAsB,EAAE,cAAc,EAGlD,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,EAAE,cAAc,EAMlD,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,qBAAqB,EAAE,cAAc,EAEjD,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,EAAE,cAAc,EAQnD,CAAC;AAEF,uBAAuB;AACvB,eAAO,MAAM,sBAAsB,EAAE,cAAc,EAMlD,CAAC;AAIF,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,EAalD,CAAC;AAIF,eAAO,MAAM,2BAA2B,EAAE,wBAAwB,EAcjE,CAAC;AAIF,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,EAsBtD,CAAC;AAIF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAOvE,CAAC;AAIF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAKpE,CAAC"}