deuk-agent-rule 1.0.2 → 1.0.5

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/README.ko.md CHANGED
@@ -1,78 +1,93 @@
1
1
  # DeukAgentRules (득에이전트룰스)
2
2
 
3
+ > **Deuk Family**의 핵심 모듈 가운데 하나입니다. 구조화된 규칙으로 AI 에이전트의 협업과 응답을 다듬습니다.
4
+
3
5
  **npm 패키지:** `deuk-agent-rule` · **CLI:** `deuk-agent-rule`
4
6
 
5
- **English:** [README.md](README.md)
7
+ **English:** [README.md](https://github.com/joygram/DeukAgentRules/blob/master/README.md)
6
8
 
7
9
  Cursor, Copilot, Gemini 등 여러 에이전트·도구를 함께 쓸 때를 위한 `AGENTS.md`·`.cursor/rules` 버전 관리형 템플릿. 핸드오프·간결 응답으로 비용·성능을 개선합니다.
8
10
 
9
11
  ## 워크스페이스 초기화
10
12
 
11
- 설치만으로는 파일이 바뀌지 않습니다. **대상 프로젝트 루트**에서 CLI를 실행하거나 `--cwd`로 경로를 줍니다.
12
-
13
13
  ```bash
14
14
  npm install deuk-agent-rule
15
15
  npx deuk-agent-rule init
16
16
  ```
17
17
 
18
- 적용 흐름:
18
+ `--non-interactive` 없이 실행하면 짧은 설정 질문이 시작됩니다:
19
19
 
20
- 1. `AGENTS.md`를 둘 프로젝트 루트로 이동.
21
- 2. `npm install deuk-agent-rule` (devDependency 권장 가능).
22
- 3. `npx deuk-agent-rule init` — 마커가 없으면 끝에 `<!-- deuk-agent-rule:begin -->` … `<!-- deuk-agent-rule:end -->` 블록을 붙이고 안쪽을 번들 템플릿으로 채움. `.mdc`는 `.cursor/rules/`에 복사(이름 충돌 시 기본 **prefix**).
20
+ ```
21
+ $ npx deuk-agent-rule init
22
+
23
+ DeukAgentRules init — let's configure your workspace.
24
+
25
+ ? What is your primary tech stack?
26
+ 1) Unity / C#
27
+ 2) Next.js + C#
28
+ 3) Web (React / Vue / general)
29
+ 4) Java / Spring Boot
30
+ 5) Other / skip
31
+ Choice [1-5]: 1
32
+
33
+ ? Which agent tools do you use? (comma-separated numbers, or 'all')
34
+ 1) Cursor
35
+ 2) GitHub Copilot
36
+ 3) Gemini / Antigravity
37
+ 4) All of the above
38
+ 5) Other / skip
39
+ Choices: 1,2
40
+
41
+ Stack : unity
42
+ Tools : cursor, copilot
43
+
44
+ AGENTS.md: injected (inject)
45
+ rule copied: .cursor/rules/deuk-agent-rule-multi-ai-workflow.mdc
46
+ rule copied: .cursor/rules/deuk-agent-rule-delivery-and-parallel-work.mdc
47
+ rule copied: .cursor/rules/deuk-agent-rule-git-commit.mdc
48
+ ```
23
49
 
24
- 패키지 업데이트 후:
50
+ CI나 스크립트 환경에서 질문 없이 실행:
25
51
 
26
52
  ```bash
27
- npm update deuk-agent-rule
28
- npx deuk-agent-rule init
53
+ npx deuk-agent-rule init --non-interactive
29
54
  ```
30
55
 
31
- `AGENTS.md`에서는 **마커 안**만 다시 갱신되고, 바깥 내용은 유지됩니다.
32
-
33
- ### `init` 파라미터
34
-
35
- 플래그는 모두 `init` **뒤**에 둡니다. 예: `npx deuk-agent-rule init --cwd ../다른레포 --dry-run`
36
-
37
- | 플래그 | init 기본값 | 설명 |
38
- |--------|-------------|------|
39
- | `--cwd <path>` | 현재 디렉터리 | `AGENTS.md`·`.cursor/rules/`를 쓸 레포 루트. |
40
- | `--dry-run` | 끔 | 쓰기 없이 할 일만 출력. |
41
- | `--backup` | 끔 | 덮어쓰기 전 같은 이름에 `.bak` 저장. |
42
- | `--tag <id>` | `deuk-agent-rule` | `<!-- <id>:begin -->` ~ `<!-- <id>:end -->` 마커 쌍. |
43
- | `--marker-begin` / `--marker-end` | (`--tag` 권장) | 임의 마커 문자열, **둘 다** 필요. |
44
- | `--agents <mode>` | `inject` | `inject` — 마커 안만 갱신(마커 없으면 블록 추가). `skip` — `AGENTS.md` 건드리지 않음. `overwrite` — 전체 교체(주의). |
45
- | `--rules <mode>` | `prefix` | `prefix` — 있으면 `deuk-agent-rule-foo.mdc`로 추가. `skip` — 스킵. `overwrite` — 덮어쓰기. |
46
- | `--append-if-no-markers` | 끔 | `merge`에서 주로 사용. |
47
-
48
- 예시:
56
+ 패키지 업데이트 후:
49
57
 
50
58
  ```bash
51
- npx deuk-agent-rule init --cwd /path/to/repo
52
- npx deuk-agent-rule init --dry-run
53
- npx deuk-agent-rule init --tag mycompany --rules overwrite
54
- npx deuk-agent-rule init --agents skip --rules prefix
55
- npx deuk-agent-rule init --backup
59
+ npm update deuk-agent-rule
60
+ npx deuk-agent-rule init --non-interactive
56
61
  ```
57
62
 
58
- ### 동작 모델
63
+ `AGENTS.md`의 **마커 안**만 갱신되고 바깥 내용은 유지됩니다.
64
+
65
+ ### 주요 옵션
59
66
 
60
- - **관리 구역**: 마커 **사이**만 패키지가 갱신.
61
- - **`.mdc`**: 별도 파일로 복사; 기본 `prefix`로 기존 파일 보호.
67
+ | 플래그 | 기본값 | 설명 |
68
+ |--------|--------|------|
69
+ | `--non-interactive` | 끔 | 질문 생략, 플래그 기본값으로 실행 |
70
+ | `--cwd <path>` | 현재 디렉터리 | 대상 레포 루트 |
71
+ | `--dry-run` | 끔 | 쓰기 없이 동작만 출력 |
72
+ | `--tag <id>` | `deuk-agent-rule` | 마커 id: `<!-- <id>:begin/end -->` |
73
+ | `--agents <mode>` | `inject` | `inject` \| `skip` \| `overwrite` |
74
+ | `--rules <mode>` | `prefix` | `prefix` \| `skip` \| `overwrite` |
75
+ | `--backup` | 끔 | 덮어쓰기 전 `*.bak` 저장 |
62
76
 
63
- ### 번들에 포함되는 규칙
77
+ ### 번들 규칙
64
78
 
65
79
  - **`multi-ai-workflow.mdc`** — `alwaysApply: true`
80
+ - **`delivery-and-parallel-work.mdc`** — `alwaysApply: true` (세로 슬라이스·포트폴리오 우선·병렬 소유·리팩터 범위 축소)
66
81
  - **`git-commit.mdc`** — `alwaysApply: false`
67
82
 
68
83
  ### `merge` (엄격)
69
84
 
70
- 옵션은 동일. 마커가 없으면 `inject`는 실패(`--append-if-no-markers` 없을 때). 기본 `--rules skip`.
85
+ 옵션 동일. 마커가 없으면 inject 실패(`--append-if-no-markers` 없을 때). 기본 `--rules skip`.
71
86
 
72
87
  ### 주의
73
88
 
74
- - `alwaysApply: true` 규칙이 겹치면 컨텍스트가 길어질있음.
75
- - `postinstall`에서 `init` 자동 실행은 권장하지 않음.
89
+ - `alwaysApply: true` 규칙이 겹치면 컨텍스트가 커질있습니다.
90
+ - `postinstall`에서 `init` 자동 실행은 권장하지 않습니다.
76
91
 
77
92
  ## 버전
78
93
 
package/README.md CHANGED
@@ -1,78 +1,92 @@
1
1
  # DeukAgentRules
2
2
 
3
+ > **Part of the Deuk Family** — Empowering AI Agents with structured rules.
4
+
3
5
  **npm package:** `deuk-agent-rule` · **CLI:** `deuk-agent-rule`
4
6
 
5
- **한국어:** [README.ko.md](README.ko.md)
7
+ **한국어:** [README.ko.md](https://github.com/joygram/DeukAgentRules/blob/master/README.ko.md)
6
8
 
7
9
  Versioned templates for `AGENTS.md` and `.cursor/rules` for Cursor, Copilot, Gemini and similar agents: shared handoff format, concise execution, stronger cost-efficiency and responsiveness.
8
10
 
9
11
  ## Initialize a workspace
10
12
 
11
- Install does nothing until you run the CLI from the **target repository root** (or pass `--cwd`).
12
-
13
13
  ```bash
14
14
  npm install deuk-agent-rule
15
15
  npx deuk-agent-rule init
16
16
  ```
17
17
 
18
- Typical first run:
18
+ Running `init` without `--non-interactive` starts a short setup flow:
19
19
 
20
- 1. `cd` into your project root (where `AGENTS.md` should live).
21
- 2. `npm install deuk-agent-rule` (devDependency is fine).
22
- 3. `npx deuk-agent-rule init` — appends `<!-- deuk-agent-rule:begin -->` … `<!-- deuk-agent-rule:end -->` if missing, fills the inner region with the bundled template, and copies `.mdc` files under `.cursor/rules/` (default **prefix** on name clash).
20
+ ```
21
+ $ npx deuk-agent-rule init
22
+
23
+ DeukAgentRules init — let's configure your workspace.
24
+
25
+ ? What is your primary tech stack?
26
+ 1) Unity / C#
27
+ 2) Next.js + C#
28
+ 3) Web (React / Vue / general)
29
+ 4) Java / Spring Boot
30
+ 5) Other / skip
31
+ Choice [1-5]: 3
32
+
33
+ ? Which agent tools do you use? (comma-separated numbers, or 'all')
34
+ 1) Cursor
35
+ 2) GitHub Copilot
36
+ 3) Gemini / Antigravity
37
+ 4) All of the above
38
+ 5) Other / skip
39
+ Choices: all
40
+
41
+ Stack : web
42
+ Tools : cursor, copilot, gemini, all
43
+
44
+ AGENTS.md: injected (inject)
45
+ rule copied: .cursor/rules/deuk-agent-rule-multi-ai-workflow.mdc
46
+ rule copied: .cursor/rules/deuk-agent-rule-delivery-and-parallel-work.mdc
47
+ rule copied: .cursor/rules/deuk-agent-rule-git-commit.mdc
48
+ ```
23
49
 
24
- After a package upgrade:
50
+ To skip questions (CI or scripted use):
25
51
 
26
52
  ```bash
27
- npm update deuk-agent-rule
28
- npx deuk-agent-rule init
53
+ npx deuk-agent-rule init --non-interactive
29
54
  ```
30
55
 
31
- Only the **marker region** in `AGENTS.md` is replaced again; your text outside the markers stays.
32
-
33
- ### `init` parameters
34
-
35
- All flags go **after** `init` (e.g. `npx deuk-agent-rule init --cwd ../other-repo --dry-run`).
36
-
37
- | Flag | Default (init) | Description |
38
- |------|----------------|-------------|
39
- | `--cwd <path>` | current directory | Root of the repo to modify (`AGENTS.md`, `.cursor/rules/`). |
40
- | `--dry-run` | off | Print planned actions; do not write files. |
41
- | `--backup` | off | Write `*.bak` next to any file that would be overwritten. |
42
- | `--tag <id>` | `deuk-agent-rule` | HTML comment markers: `<!-- <id>:begin -->` … `<!-- <id>:end -->`. |
43
- | `--marker-begin <s>` / `--marker-end <s>` | (use `--tag` instead) | Custom marker strings; **both** required if either is set. |
44
- | `--agents <mode>` | `inject` | `inject` — update only inside markers (or append block if no markers). `skip` — do not change `AGENTS.md`. `overwrite` — replace entire `AGENTS.md` with the bundle (use with care). |
45
- | `--rules <mode>` | `prefix` | `prefix` — if `foo.mdc` exists, write `deuk-agent-rule-foo.mdc`. `skip` — skip existing names. `overwrite` — replace on clash. |
46
- | `--append-if-no-markers` | off | Rare for `init` (init already appends when markers are missing). Same flag is mainly for `merge`. |
47
-
48
- Examples:
56
+ After a package upgrade:
49
57
 
50
58
  ```bash
51
- npx deuk-agent-rule init --cwd /path/to/repo
52
- npx deuk-agent-rule init --dry-run
53
- npx deuk-agent-rule init --tag mycompany --rules overwrite
54
- npx deuk-agent-rule init --agents skip --rules prefix
55
- npx deuk-agent-rule init --backup
59
+ npm update deuk-agent-rule
60
+ npx deuk-agent-rule init --non-interactive
56
61
  ```
57
62
 
58
- ### Product model
63
+ Only the **marker region** in `AGENTS.md` is replaced; your text outside stays.
64
+
65
+ ### Key options
59
66
 
60
- - **Managed block in `AGENTS.md`**: Between `<!-- deuk-agent-rule:begin -->` and `<!-- deuk-agent-rule:end -->` (or your `--tag`) — `init` / `merge` replace **only** that inner content with the bundled template.
61
- - **Updates**: Re-run `init` after `npm update` to refresh the managed block idempotently.
62
- - **`.mdc`**: Copied as **separate files**; default `prefix` avoids overwriting your existing rules.
67
+ | Flag | Default | Description |
68
+ |------|---------|-------------|
69
+ | `--non-interactive` | off | Skip questions; use flag defaults |
70
+ | `--cwd <path>` | current directory | Target repo root |
71
+ | `--dry-run` | off | Print actions without writing |
72
+ | `--tag <id>` | `deuk-agent-rule` | Marker id: `<!-- <id>:begin/end -->` |
73
+ | `--agents <mode>` | `inject` | `inject` \| `skip` \| `overwrite` |
74
+ | `--rules <mode>` | `prefix` | `prefix` \| `skip` \| `overwrite` |
75
+ | `--backup` | off | Write `*.bak` before overwrite |
63
76
 
64
77
  ### Bundled rules
65
78
 
66
79
  - **`multi-ai-workflow.mdc`** — `alwaysApply: true`
80
+ - **`delivery-and-parallel-work.mdc`** — `alwaysApply: true` (vertical slices, portfolio priority, parallel ownership, scoped refactors)
67
81
  - **`git-commit.mdc`** — `alwaysApply: false`
68
82
 
69
83
  ### `merge` (stricter)
70
84
 
71
- Same flags; **`AGENTS.md` `inject` fails if markers are missing** unless `--append-if-no-markers`. Default **`--rules skip`**.
85
+ Same flags; `AGENTS.md` inject fails without markers unless `--append-if-no-markers`. Default `--rules skip`.
72
86
 
73
87
  ### Caveats
74
88
 
75
- - Multiple `alwaysApply: true` rule files (yours + prefixed copies) all apply — trim duplicates if context grows too large.
89
+ - Multiple `alwaysApply: true` rules all apply — trim duplicates if context grows too large.
76
90
  - Do **not** run `init` from `postinstall` without an explicit team decision.
77
91
 
78
92
  ## Versioning
package/bundle/AGENTS.md CHANGED
@@ -22,6 +22,13 @@ Senior software engineer. Correctness, minimal diffs, safety.
22
22
  - **One clear objective** per session or turn when practical; do not expand scope into unrelated refactors.
23
23
  - For read-only or exploratory tasks, **summarize** and point to paths instead of pasting large blobs.
24
24
 
25
+ ## Delivery, portfolio, and parallel work
26
+
27
+ - Prefer **one PR or session outcome = one vertical slice**: integrated, buildable, and **demo-able** for that slice unless the user explicitly requests a broad-only refactor.
28
+ - When the user signals **portfolio / demo / ship-now priority**, **narrow** work to visible outcomes first; defer wide cleanups to a separate scoped task unless blocking.
29
+ - Under **parallel branches or shared ownership**, keep edits **small and bounded** on hot shared paths; respect named lane or directory ownership when given; flag high-conflict paths instead of silently expanding scope.
30
+ - **Default to minimal refactor**: satisfy the task with the smallest structural change; split optional large refactors into a follow-up handoff instead of bundling them.
31
+
25
32
  ## IDE Branding
26
33
 
27
34
  No editor or vendor tool branding in code, docs, README, commits, or published artifacts.
@@ -33,6 +40,7 @@ No editor or vendor tool branding in code, docs, README, commits, or published a
33
40
  - **문서**: 사용자에게 보이는 동작·호환·패키징·보안 위주. 내부 절차 전문을 그대로 붙여 넣지 않음.
34
41
  - **브랜딩**: 코드·문서·README·커밋·배포물에 에디터·벤더 도구 이름을 넣지 않음.
35
42
  - **비용·효율**: 짧고 신호가 큰 답·패치 위주; 불필요한 장문·동일 맥락 반복 지양. 한 번에 목표 하나. 읽기 전용 작업은 요약과 경로 위주.
43
+ - **전달·병렬**: PR/세션 단위는 데모 가능한 세로 슬라이스 우선. 포트폴리오·출시 우선 시 범위 축소. 병렬 갈래·소유 구역 존중, 핫 경로는 최소 변경.
36
44
 
37
45
  English sections above are canonical for tooling; this block is a short Korean mirror for the same rules.
38
46
 
@@ -0,0 +1,26 @@
1
+ ---
2
+ description: Vertical slices, portfolio priority, parallel-branch ownership, scoped refactors
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Delivery, portfolio, and parallel work
7
+
8
+ ## Default shape of work
9
+
10
+ - Prefer **one PR (or one agent session outcome) = one vertically integrated slice**: buildable, runnable, and **demo-able** end-to-end for that slice. Do not treat “wide refactors with no user-visible behavior” as the default unit of delivery unless the user explicitly asks for that.
11
+ - When the user states **portfolio, demo, or ship-this-week priority**, treat that as **scope authority**: narrow the task to what improves the visible outcome first; defer broad cleanups to a follow-up handoff unless they are blocking the slice.
12
+
13
+ ## Parallel branches and file ownership
14
+
15
+ - Assume **other branches or developers may be editing the same repo**. Before touching widely shared files (large pages, shared `lib/`, config roots), **minimize blast radius**: prefer a small, well-bounded edit over sweeping moves in the same change set.
16
+ - If the user names an **owner branch, feature lane, or file ownership** (e.g. “UI lane owns `components/`, gameplay owns `lib/game/`”), **stay inside that boundary** unless they explicitly expand it.
17
+ - When parallel work is likely, **call out** touched paths that are high-merge-conflict risk so the user can coordinate; do not silently expand into those files without need.
18
+
19
+ ## Refactor discipline
20
+
21
+ - **Shrink refactor scope by default**: extract or adjust only what the current task requires. If a larger refactor is tempting, split it: **(1)** minimal change that satisfies the task, **(2)** optional follow-up task in handoff format.
22
+ - Do not use “while we’re here” to rename, reformat, or reorganize unrelated modules.
23
+
24
+ ## Interaction with handoffs
25
+
26
+ - If a handoff or user message defines **Files to modify** and **Constraints**, those win; this rule file **narrows** how you plan and execute within that envelope — it does not override explicit file lists.
package/package.json CHANGED
@@ -1,7 +1,16 @@
1
1
  {
2
2
  "name": "deuk-agent-rule",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "DeukAgentRules: generic AGENTS.md + .cursor rule templates with init/merge CLI (npm name: deuk-agent-rule).",
5
+ "keywords": [
6
+ "agents-md",
7
+ "cursor-rules",
8
+ "copilot",
9
+ "gemini",
10
+ "handoff",
11
+ "deuk-family",
12
+ "deukpack-ecosystem"
13
+ ],
5
14
  "license": "Apache-2.0",
6
15
  "files": [
7
16
  "bundle/**/*",
package/scripts/cli.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync } from "fs";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { createInterface } from "readline";
3
4
  import { dirname, join } from "path";
4
5
  import { fileURLToPath } from "url";
5
6
  import {
@@ -13,9 +14,122 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
13
14
  const pkgRoot = join(__dirname, "..");
14
15
  const bundleRoot = join(pkgRoot, "bundle");
15
16
 
17
+ // ---------------------------------------------------------------------------
18
+ // Interactive prompt helpers (no external deps)
19
+ // ---------------------------------------------------------------------------
20
+
21
+ function isNonInteractive(opts) {
22
+ return opts.nonInteractive || process.env.CI || !process.stdin.isTTY;
23
+ }
24
+
25
+ async function ask(rl, question) {
26
+ return new Promise((resolve) => rl.question(question, resolve));
27
+ }
28
+
29
+ async function selectOne(rl, prompt, choices) {
30
+ console.log("\n" + prompt);
31
+ choices.forEach((c, i) => console.log(` ${i + 1}) ${c.label}`));
32
+ while (true) {
33
+ const ans = (await ask(rl, ` Choice [1-${choices.length}]: `)).trim();
34
+ const idx = parseInt(ans, 10) - 1;
35
+ if (idx >= 0 && idx < choices.length) return choices[idx].value;
36
+ console.log(" Please enter a number between 1 and " + choices.length);
37
+ }
38
+ }
39
+
40
+ async function selectMany(rl, prompt, choices) {
41
+ console.log("\n" + prompt + " (comma-separated numbers, or 'all')");
42
+ choices.forEach((c, i) => console.log(` ${i + 1}) ${c.label}`));
43
+ while (true) {
44
+ const ans = (await ask(rl, ` Choices: `)).trim().toLowerCase();
45
+ if (ans === "all" || ans === "") return choices.map((c) => c.value);
46
+ const parts = ans.split(/[,\s]+/).map((s) => parseInt(s, 10) - 1);
47
+ if (parts.every((i) => i >= 0 && i < choices.length)) {
48
+ return parts.map((i) => choices[i].value);
49
+ }
50
+ console.log(" Invalid selection, try again.");
51
+ }
52
+ }
53
+
54
+ const STACKS = [
55
+ { label: "Unity / C#", value: "unity" },
56
+ { label: "Next.js + C#", value: "nextjs-dotnet" },
57
+ { label: "Web (React / Vue / general)", value: "web" },
58
+ { label: "Java / Spring Boot", value: "java" },
59
+ { label: "Other / skip", value: "other" },
60
+ ];
61
+
62
+ const AGENT_TOOLS = [
63
+ { label: "Cursor", value: "cursor" },
64
+ { label: "GitHub Copilot", value: "copilot" },
65
+ { label: "Gemini / Antigravity", value: "gemini" },
66
+ { label: "All of the above", value: "all" },
67
+ { label: "Other / skip", value: "other" },
68
+ ];
69
+
70
+ async function runInteractive(opts) {
71
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
72
+ try {
73
+ console.log("\nDeukAgentRules init — let's configure your workspace.\n");
74
+
75
+ const stack = await selectOne(rl, "What is your primary tech stack?", STACKS);
76
+ const tools = await selectMany(rl, "Which agent tools do you use?", AGENT_TOOLS);
77
+
78
+ const targetAgents = join(opts.cwd, "AGENTS.md");
79
+ let agentsDefault = "inject";
80
+ if (!existsSync(targetAgents)) {
81
+ agentsDefault = "inject"; // will append markers
82
+ console.log("\n No AGENTS.md found — will create with markers.");
83
+ } else {
84
+ const content = readFileSync(targetAgents, "utf8");
85
+ const hasMarkers = content.includes("deuk-agent-rule:begin");
86
+ if (!hasMarkers) {
87
+ const choice = await selectOne(rl, "AGENTS.md exists but has no markers. How to apply?", [
88
+ { label: "Append managed block at the end (safe)", value: "inject" },
89
+ { label: "Overwrite entire AGENTS.md", value: "overwrite" },
90
+ { label: "Skip AGENTS.md", value: "skip" },
91
+ ]);
92
+ agentsDefault = choice;
93
+ }
94
+ }
95
+
96
+ opts.agents = opts.agents ?? agentsDefault;
97
+ opts.stack = stack;
98
+ opts.agentTools = tools;
99
+
100
+ console.log("\n Stack : " + stack);
101
+ console.log(" Tools : " + (tools.join(", ") || "none"));
102
+ console.log(" AGENTS: " + opts.agents + "\n");
103
+ } finally {
104
+ rl.close();
105
+ }
106
+ }
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // Help / arg parsing
110
+ // ---------------------------------------------------------------------------
111
+
16
112
  function printHelp() {
17
113
  console.log(
18
- "DeukAgentRules (npm: deuk-agent-rule) — AGENTS.md + .cursor/rules templates\n\nUsage:\n npx deuk-agent-rule init [options]\n npx deuk-agent-rule merge [options]\n\nPrimary flow:\n npm install deuk-agent-rule\n npx deuk-agent-rule init\n\nOptions:\n --cwd <path>\n --dry-run\n --backup\n --tag <id>\n --marker-begin <string>\n --marker-end <string>\n\ninit defaults: agents inject (append markers if missing), rules prefix\nmerge defaults: agents inject (fail if no markers unless --append-if-no-markers), rules skip\n\nAlso:\n --agents skip|overwrite|inject\n --rules skip|overwrite|prefix\n --append-if-no-markers\n\nKorean: package README.ko.md\n",
114
+ `DeukAgentRules (npm: deuk-agent-rule) — AGENTS.md + .cursor/rules templates
115
+
116
+ Usage:
117
+ npx deuk-agent-rule init [options] # interactive by default
118
+ npx deuk-agent-rule merge [options]
119
+
120
+ Options:
121
+ --cwd <path> Target repo root (default: current directory)
122
+ --dry-run Print actions; do not write files
123
+ --non-interactive Skip questions; use defaults/flags directly
124
+ --tag <id> Marker id (default: deuk-agent-rule)
125
+ --agents <mode> inject | skip | overwrite
126
+ --rules <mode> prefix | skip | overwrite
127
+ --backup Write *.bak before overwrite
128
+ --append-if-no-markers
129
+ --marker-begin / --marker-end Custom marker strings (both required)
130
+
131
+ Korean: package README.ko.md
132
+ `,
19
133
  );
20
134
  }
21
135
 
@@ -30,6 +144,7 @@ function parseArgs(argv) {
30
144
  agents: undefined,
31
145
  rules: undefined,
32
146
  appendIfNoMarkers: false,
147
+ nonInteractive: false,
33
148
  };
34
149
  for (let i = 0; i < argv.length; i++) {
35
150
  const a = argv[i];
@@ -38,6 +153,7 @@ function parseArgs(argv) {
38
153
  if (!out.cwd) throw new Error("--cwd requires a path");
39
154
  } else if (a === "--dry-run") out.dryRun = true;
40
155
  else if (a === "--backup") out.backup = true;
156
+ else if (a === "--non-interactive") out.nonInteractive = true;
41
157
  else if (a === "--tag") {
42
158
  out.tag = argv[++i];
43
159
  if (out.tag == null) throw new Error("--tag requires a value");
@@ -70,6 +186,10 @@ function validateMode(name, v, allowed) {
70
186
  }
71
187
  }
72
188
 
189
+ // ---------------------------------------------------------------------------
190
+ // init / merge runners
191
+ // ---------------------------------------------------------------------------
192
+
73
193
  function runInit(opts) {
74
194
  const markers = resolveMarkers({
75
195
  tag: opts.tag,
@@ -150,7 +270,11 @@ function runMerge(opts) {
150
270
  }
151
271
  }
152
272
 
153
- function main() {
273
+ // ---------------------------------------------------------------------------
274
+ // Entry point
275
+ // ---------------------------------------------------------------------------
276
+
277
+ async function main() {
154
278
  const argv = process.argv.slice(2);
155
279
  const sub = argv[0];
156
280
  if (!sub || sub === "-h" || sub === "--help") {
@@ -175,13 +299,16 @@ function main() {
175
299
 
176
300
  if (!existsSync(bundleRoot)) {
177
301
  console.error(
178
- "Missing bundle/ (run from published package or run npm run sync in deuk-agent-rule when developing in the monorepo).",
302
+ "Missing bundle/ (run from published package or run npm run sync in DeukAgentRules when developing).",
179
303
  );
180
304
  process.exit(1);
181
305
  }
182
306
 
183
307
  try {
184
308
  if (sub === "init") {
309
+ if (!isNonInteractive(opts)) {
310
+ await runInteractive(opts);
311
+ }
185
312
  runInit(opts);
186
313
  } else if (sub === "merge") {
187
314
  runMerge(opts);
@@ -29,6 +29,9 @@ mkdirSync(join(ossRoot, "scripts"), { recursive: true });
29
29
  mkdirSync(join(ossRoot, "publish"), { recursive: true });
30
30
 
31
31
  cpSync(join(pkgRoot, "publish"), join(ossRoot, "publish"), { recursive: true, force: true });
32
+ if (existsSync(join(pkgRoot, ".github"))) {
33
+ cpSync(join(pkgRoot, ".github"), join(ossRoot, ".github"), { recursive: true, force: true });
34
+ }
32
35
  cpSync(join(pkgRoot, "scripts", "cli.mjs"), join(ossRoot, "scripts", "cli.mjs"), { force: true });
33
36
  cpSync(join(pkgRoot, "scripts", "merge-logic.mjs"), join(ossRoot, "scripts", "merge-logic.mjs"), {
34
37
  force: true,
@@ -42,6 +45,12 @@ if (!existsSync(ossPublic)) {
42
45
  }
43
46
  cpSync(join(pkgRoot, "README.md"), join(ossRoot, "README.md"), { force: true });
44
47
  cpSync(join(pkgRoot, "README.ko.md"), join(ossRoot, "README.ko.md"), { force: true });
48
+ if (existsSync(join(pkgRoot, "package-lock.json"))) {
49
+ cpSync(join(pkgRoot, "package-lock.json"), join(ossRoot, "package-lock.json"), { force: true });
50
+ }
51
+ if (existsSync(join(pkgRoot, "LICENSE"))) {
52
+ cpSync(join(pkgRoot, "LICENSE"), join(ossRoot, "LICENSE"), { force: true });
53
+ }
45
54
  cpSync(join(ossPublic, "RELEASING.md"), join(ossRoot, "RELEASING.md"), { force: true });
46
55
  cpSync(join(ossPublic, "RELEASING.ko.md"), join(ossRoot, "RELEASING.ko.md"), { force: true });
47
56
  cpSync(join(ossPublic, "GITHUB_DESCRIPTION.md"), join(ossRoot, "GITHUB_DESCRIPTION.md"), {
@@ -51,7 +60,7 @@ cpSync(join(ossPublic, "GITHUB_DESCRIPTION.md"), join(ossRoot, "GITHUB_DESCRIPTI
51
60
  const srcPkg = JSON.parse(readFileSync(join(pkgRoot, "package.json"), "utf8"));
52
61
  const outPkg = {
53
62
  ...srcPkg,
54
- license: "MIT",
63
+ license: srcPkg.license || "Apache-2.0",
55
64
  repository: {
56
65
  type: "git",
57
66
  url: gitUrl,