agent-work-loop 0.6.43 → 0.6.45

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 (50) hide show
  1. package/README.md +3 -3
  2. package/dist/{brief-GOGJDLY7.js → brief-SGMFXOY2.js} +5 -5
  3. package/dist/{changelog-NLYZTB44.js → changelog-VNJ4EQ74.js} +5 -5
  4. package/dist/{chunk-SKLSWS5J.js → chunk-5MXSJD3C.js} +2 -2
  5. package/dist/{chunk-I5SS6HFR.js → chunk-DQF7RF37.js} +11 -11
  6. package/dist/{chunk-MBEY33YA.js → chunk-EHJYX57P.js} +2 -2
  7. package/dist/{chunk-UNAASSQ4.js → chunk-FGHILN3D.js} +6 -0
  8. package/dist/{chunk-QVP5DUND.js → chunk-FK3Q7UY2.js} +3 -3
  9. package/dist/{chunk-TQUXHTN5.js → chunk-HAUTKVB5.js} +4 -4
  10. package/dist/{chunk-JQV65R3M.js → chunk-IA32FVBA.js} +6 -7
  11. package/dist/{chunk-I5WWLNA6.js → chunk-ISLNBWKV.js} +13 -13
  12. package/dist/{chunk-SOUTYYY4.js → chunk-IVEV5L7P.js} +2 -2
  13. package/dist/{chunk-JR6MKCC4.js → chunk-MLTY3EE6.js} +62 -3
  14. package/dist/{chunk-OVLA5DET.js → chunk-PUINOFOR.js} +5 -7
  15. package/dist/{chunk-YC23SNVC.js → chunk-QKKMA2VT.js} +5 -5
  16. package/dist/{chunk-7CPPZX6X.js → chunk-SJG22DAK.js} +27 -6
  17. package/dist/{chunk-UJ6CK5HC.js → chunk-VE2GVNNS.js} +2 -2
  18. package/dist/{chunk-I3WXYD5C.js → chunk-VVZOIFL4.js} +1 -1
  19. package/dist/{chunk-E6MULIMV.js → chunk-ZRKOZQKP.js} +5 -5
  20. package/dist/cli.js +58 -46
  21. package/dist/{commit-BKN3ZJI7.js → commit-GPQATPEA.js} +6 -6
  22. package/dist/{config-DX3WL2JT.js → config-QTEKLFZP.js} +3 -3
  23. package/dist/{doctor-TBRNCTDS.js → doctor-TMMIO4CE.js} +8 -8
  24. package/dist/{evolve-EMGWWWY3.js → evolve-N3S32P5I.js} +7 -7
  25. package/dist/{feedback-ZAAM5VYL.js → feedback-log-UCNJ2GVT.js} +11 -11
  26. package/dist/{gotchas-6ZWHP5Z6.js → gotchas-PDG2ZZFQ.js} +7 -7
  27. package/dist/{hold-recheck-K7DV64KW.js → hold-recheck-UNAILFN5.js} +6 -17
  28. package/dist/{init-3X6NVQQW.js → init-3B4ZRGWY.js} +2 -2
  29. package/dist/lane-24GAVVR6.js +39 -0
  30. package/dist/{loop-summary-CD6EIAHZ.js → loop-summary-CODZMRUY.js} +6 -6
  31. package/dist/{metrics-VVXCH6TR.js → metrics-ZR7BPATB.js} +4 -4
  32. package/dist/{record-AC7LPU36.js → record-TSB22DIO.js} +5 -5
  33. package/dist/{remove-C64QRELY.js → remove-J7B32U75.js} +16 -16
  34. package/dist/{review-VCVPT3P6.js → review-EM5Q2ZJX.js} +15 -15
  35. package/dist/{rules-2DIFP7K2.js → rules-QLUXNSCN.js} +8 -8
  36. package/dist/{state-UIHEGC5P.js → state-6IIH7SW2.js} +4 -4
  37. package/dist/status-2LPWVCHT.js +29 -0
  38. package/dist/{update-KCQWDQDF.js → update-CKGPHO5B.js} +2 -2
  39. package/dist/{verify-Y36JFAA7.js → verify-VWKIBPZD.js} +10 -10
  40. package/dist/version-check-3BZXXAQD.js +14 -0
  41. package/dist/{work-HHTQTJZW.js → work-PEJN55JB.js} +14 -14
  42. package/engine/skills/claude/awl-loop/reference.md +1 -1
  43. package/engine/skills/claude/awl-pipeline/SKILL.md +1 -1
  44. package/engine/templates/block-publish.mjs +20 -2
  45. package/engine/templates/pre-push.sample +8 -2
  46. package/engine/version.json +1 -1
  47. package/package.json +1 -1
  48. package/dist/lane-QPZE7KYI.js +0 -41
  49. package/dist/status-2PUVZCFI.js +0 -40
  50. package/dist/version-check-XLXT7NSG.js +0 -14
package/README.md CHANGED
@@ -136,7 +136,7 @@ $ awl init
136
136
  - **`.awl/config.json`**: 검증 명령과 프로젝트 성격. **커밋하세요.** 팀원이 같이 씁니다.
137
137
  - **`.awl/state.json`**: 지금 어느 워크아이템의 어느 단계인지. gitignore 대상입니다.
138
138
  - **`.claude/skills/`** 또는 **`AGENTS.md`**: 작업 루프 스킬. 선택한 에이전트에 설치됩니다.
139
- - **`.git/hooks/pre-push`**: `AWL_ALLOW_PUSH=1` 없이는 `git push`를 막는 훅. "push는 사람이 한다"는 규칙을 git 레벨에서도 강제합니다(사람이 push 때는 `AWL_ALLOW_PUSH=1 git push`로 명시적으로 통과시킵니다).
139
+ - **`.git/hooks/pre-push`**: "push는 사람이 한다"는 규칙을 git 레벨에서도 강제하는 훅. 사람이 실제 터미널에서 직접 치는 `git push`는 그냥 통과합니다(제어 터미널이 잡히는지로 판별). 에이전트가 비대화형으로 실행한 push는 막히고, 이 경우엔 `AWL_ALLOW_PUSH=1 git push`로 명시적으로 통과시켜야 합니다.
140
140
 
141
141
  이제 에이전트(Claude Code / Codex)를 열고 목표를 서술문으로 줍니다.
142
142
 
@@ -233,7 +233,7 @@ awl records # 쌓인 기록
233
233
  awl gotchas # 아직 규칙이 안 된 교훈
234
234
  awl rules # 이 프로젝트에 적용되는 규칙
235
235
  awl metrics # 워크아이템 세대별 지표 추세
236
- awl feedback # awl 도구 자체에 대한 피드백
236
+ awl feedback-log # awl 도구 자체에 남겨진 피드백 기록 검토
237
237
  ```
238
238
 
239
239
  ---
@@ -354,7 +354,7 @@ awl work switch <ID> # 보관된 워크아이템으로 전환
354
354
  정확한 동작입니다. 확신할 수 없으면 커밋하지 않고 사람에게 알리도록 설계했습니다. `git status`/`git diff`로 실제로 무엇이 섞였는지 확인하세요. 완료 조건마다 `awl commit <AC> -m`으로 닫고 넘어가는 습관을 들이세요(`awl commit --start`를 편집보다 먼저 호출하지 않으면 그 편집이 스냅샷에 흡수돼 격리 커밋이 무의미해집니다).
355
355
 
356
356
  **`git push`가 막힌다**
357
- `awl init`이 심는 pre-push 훅 때문입니다(위 5분 시작 참고). 정말 push하려면 `AWL_ALLOW_PUSH=1 git push`를 씁니다.
357
+ `awl init`이 심는 pre-push 훅 때문입니다(위 5분 시작 참고). 실제 터미널에서 사람이 직접 치는 push 막히지 않습니다 — 막혔다면 비대화형(에이전트, CI, 스크립트)으로 실행된 경우이고, 그때는 `AWL_ALLOW_PUSH=1 git push`를 씁니다.
358
358
 
359
359
  **대형 저장소에서 `awl lane new`/`awl work new --worktree`가 `Could not write new index file`로 실패한다**
360
360
  `git worktree add`가 기본 180초 안에 못 끝나 강제 종료됐다는 뜻입니다(대형 모노레포는
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  loadProjectName,
3
3
  readRecords
4
- } from "./chunk-QVP5DUND.js";
4
+ } from "./chunk-FK3Q7UY2.js";
5
5
  import {
6
6
  loadState
7
- } from "./chunk-UJ6CK5HC.js";
7
+ } from "./chunk-VE2GVNNS.js";
8
8
  import {
9
9
  resolveProjectRoot,
10
10
  run
11
- } from "./chunk-JR6MKCC4.js";
12
- import "./chunk-7CPPZX6X.js";
13
- import "./chunk-UNAASSQ4.js";
11
+ } from "./chunk-MLTY3EE6.js";
12
+ import "./chunk-SJG22DAK.js";
13
+ import "./chunk-FGHILN3D.js";
14
14
 
15
15
  // src/commands/brief.ts
16
16
  var KST_OFFSET_MS = 9 * 60 * 60 * 1e3;
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  readRecords
3
- } from "./chunk-QVP5DUND.js";
3
+ } from "./chunk-FK3Q7UY2.js";
4
4
  import {
5
5
  loadState
6
- } from "./chunk-UJ6CK5HC.js";
6
+ } from "./chunk-VE2GVNNS.js";
7
7
  import {
8
8
  resolveProjectRoot
9
- } from "./chunk-JR6MKCC4.js";
10
- import "./chunk-7CPPZX6X.js";
9
+ } from "./chunk-MLTY3EE6.js";
10
+ import "./chunk-SJG22DAK.js";
11
11
  import {
12
12
  caps,
13
13
  signal
14
- } from "./chunk-UNAASSQ4.js";
14
+ } from "./chunk-FGHILN3D.js";
15
15
 
16
16
  // src/commands/changelog.ts
17
17
  function runChangelogDraft(opts) {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  npmVersionCachePath
3
- } from "./chunk-UNAASSQ4.js";
3
+ } from "./chunk-FGHILN3D.js";
4
4
 
5
5
  // package.json
6
6
  var name = "agent-work-loop";
7
- var version = "0.6.43";
7
+ var version = "0.6.45";
8
8
 
9
9
  // src/core/npm-registry.ts
10
10
  import fs from "fs";
@@ -1,25 +1,25 @@
1
- import {
2
- gatherVersionInputs
3
- } from "./chunk-TQUXHTN5.js";
4
- import {
5
- checkVersions
6
- } from "./chunk-SKLSWS5J.js";
7
1
  import {
8
2
  loadProjectName,
9
3
  readRecords
10
- } from "./chunk-QVP5DUND.js";
4
+ } from "./chunk-FK3Q7UY2.js";
11
5
  import {
12
6
  loadState,
13
7
  readStateLock
14
- } from "./chunk-UJ6CK5HC.js";
8
+ } from "./chunk-VE2GVNNS.js";
9
+ import {
10
+ gatherVersionInputs
11
+ } from "./chunk-HAUTKVB5.js";
12
+ import {
13
+ checkVersions
14
+ } from "./chunk-5MXSJD3C.js";
15
15
  import {
16
16
  CommandNotFoundError,
17
17
  run,
18
18
  tokenize
19
- } from "./chunk-JR6MKCC4.js";
19
+ } from "./chunk-MLTY3EE6.js";
20
20
  import {
21
21
  listRegisteredProjects
22
- } from "./chunk-7CPPZX6X.js";
22
+ } from "./chunk-SJG22DAK.js";
23
23
  import {
24
24
  caps,
25
25
  clipToWidth,
@@ -35,7 +35,7 @@ import {
35
35
  sectionBox,
36
36
  signal,
37
37
  visibleWidth
38
- } from "./chunk-UNAASSQ4.js";
38
+ } from "./chunk-FGHILN3D.js";
39
39
 
40
40
  // src/commands/doctor.ts
41
41
  import fs from "fs";
@@ -2,14 +2,14 @@ import {
2
2
  acquireLock,
3
3
  loadGotchaList,
4
4
  releaseLock
5
- } from "./chunk-E6MULIMV.js";
5
+ } from "./chunk-ZRKOZQKP.js";
6
6
  import {
7
7
  caps,
8
8
  makeColors,
9
9
  rulesDir,
10
10
  sectionBox,
11
11
  signal
12
- } from "./chunk-UNAASSQ4.js";
12
+ } from "./chunk-FGHILN3D.js";
13
13
 
14
14
  // src/commands/rules.ts
15
15
  import { spawnSync } from "child_process";
@@ -57,6 +57,10 @@ function findProjectRoot(cwd = process.cwd()) {
57
57
  `\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. '${path.resolve(cwd)}' \uC704\uCABD\uC5D0\uC11C .git \uB610\uB294 .awl \uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.`
58
58
  );
59
59
  }
60
+ var WORKTREES_DIR = ".awl-worktrees";
61
+ function isInsideWorktreesDir(p) {
62
+ return path.resolve(p).split(path.sep).includes(WORKTREES_DIR);
63
+ }
60
64
 
61
65
  // src/core/engine.ts
62
66
  import fs2 from "fs";
@@ -543,6 +547,8 @@ export {
543
547
  lockFile,
544
548
  npmVersionCachePath,
545
549
  findProjectRoot,
550
+ WORKTREES_DIR,
551
+ isInsideWorktreesDir,
546
552
  installedEngineVersion,
547
553
  caps,
548
554
  rawModeCapable,
@@ -2,18 +2,18 @@ import {
2
2
  getCriterion,
3
3
  loadState,
4
4
  writeState
5
- } from "./chunk-UJ6CK5HC.js";
5
+ } from "./chunk-VE2GVNNS.js";
6
6
  import {
7
7
  resolveProjectRoot,
8
8
  run
9
- } from "./chunk-JR6MKCC4.js";
9
+ } from "./chunk-MLTY3EE6.js";
10
10
  import {
11
11
  caps,
12
12
  makeColors,
13
13
  recordsDir,
14
14
  sectionBox,
15
15
  signal
16
- } from "./chunk-UNAASSQ4.js";
16
+ } from "./chunk-FGHILN3D.js";
17
17
 
18
18
  // src/commands/record.ts
19
19
  import crypto from "crypto";
@@ -3,14 +3,14 @@ import {
3
3
  getLatestVersionCached,
4
4
  name,
5
5
  version
6
- } from "./chunk-SKLSWS5J.js";
6
+ } from "./chunk-5MXSJD3C.js";
7
7
  import {
8
8
  resolveProjectRoot
9
- } from "./chunk-JR6MKCC4.js";
9
+ } from "./chunk-MLTY3EE6.js";
10
10
  import {
11
11
  packageEngineDir,
12
12
  skillsVersionPath
13
- } from "./chunk-7CPPZX6X.js";
13
+ } from "./chunk-SJG22DAK.js";
14
14
  import {
15
15
  caps,
16
16
  installedEngineVersion,
@@ -19,7 +19,7 @@ import {
19
19
  makeTokens,
20
20
  sectionBox,
21
21
  signal
22
- } from "./chunk-UNAASSQ4.js";
22
+ } from "./chunk-FGHILN3D.js";
23
23
 
24
24
  // src/commands/version-check.ts
25
25
  import fs from "fs";
@@ -5,30 +5,30 @@ import {
5
5
  runWorkNew,
6
6
  sanitizeForGit,
7
7
  worktreeDirtyTracked
8
- } from "./chunk-I5WWLNA6.js";
8
+ } from "./chunk-ISLNBWKV.js";
9
9
  import {
10
10
  loadProjectName
11
- } from "./chunk-QVP5DUND.js";
11
+ } from "./chunk-FK3Q7UY2.js";
12
12
  import {
13
13
  loadState,
14
14
  writeState
15
- } from "./chunk-UJ6CK5HC.js";
15
+ } from "./chunk-VE2GVNNS.js";
16
16
  import {
17
17
  resolveProjectRoot,
18
18
  run
19
- } from "./chunk-JR6MKCC4.js";
19
+ } from "./chunk-MLTY3EE6.js";
20
20
  import {
21
+ WORKTREES_DIR,
21
22
  caps,
22
23
  feedback,
23
24
  makeColors,
24
25
  sectionBox,
25
26
  signal
26
- } from "./chunk-UNAASSQ4.js";
27
+ } from "./chunk-FGHILN3D.js";
27
28
 
28
29
  // src/commands/lane.ts
29
30
  import fs from "fs";
30
31
  import path from "path";
31
- var WORKTREES_DIR = ".awl-worktrees";
32
32
  var PIPELINE_TRIGGERS = ["/awl-pipeline-plan", "/awl-pipeline-exec", "/awl-pipeline-review"];
33
33
  function requireRoot() {
34
34
  const root = resolveProjectRoot();
@@ -303,7 +303,6 @@ ${feedback(c, "ok", `\uB808\uC778 \uC81C\uAC70 ${color.bold(laneName)}`, branch
303
303
  }
304
304
 
305
305
  export {
306
- WORKTREES_DIR,
307
306
  runLaneNew,
308
307
  parseWorktreeBranches,
309
308
  laneBranchMap,
@@ -2,39 +2,39 @@ import {
2
2
  DEFAULT_USAGE_PATH,
3
3
  readCostSnapshot
4
4
  } from "./chunk-D5OINC3G.js";
5
+ import {
6
+ parseRuleFile
7
+ } from "./chunk-EHJYX57P.js";
8
+ import {
9
+ nextGotchaId
10
+ } from "./chunk-ZRKOZQKP.js";
5
11
  import {
6
12
  buildVerifyBaseline,
7
13
  isCheckPassed,
8
14
  runVerifyChecks,
9
15
  writeVerifyBaseline
10
- } from "./chunk-YC23SNVC.js";
16
+ } from "./chunk-QKKMA2VT.js";
11
17
  import {
12
18
  gitBranch
13
- } from "./chunk-I5SS6HFR.js";
14
- import {
15
- parseRuleFile
16
- } from "./chunk-MBEY33YA.js";
17
- import {
18
- nextGotchaId
19
- } from "./chunk-E6MULIMV.js";
19
+ } from "./chunk-DQF7RF37.js";
20
20
  import {
21
21
  loadProjectName
22
- } from "./chunk-QVP5DUND.js";
22
+ } from "./chunk-FK3Q7UY2.js";
23
23
  import {
24
24
  loadState,
25
25
  migrateState,
26
26
  writeState
27
- } from "./chunk-UJ6CK5HC.js";
27
+ } from "./chunk-VE2GVNNS.js";
28
28
  import {
29
29
  loadConfig,
30
30
  multiProjectFooter,
31
31
  resolveProjectRoot,
32
32
  resolveProjectScope,
33
33
  run
34
- } from "./chunk-JR6MKCC4.js";
34
+ } from "./chunk-MLTY3EE6.js";
35
35
  import {
36
36
  installClaudeSkill
37
- } from "./chunk-7CPPZX6X.js";
37
+ } from "./chunk-SJG22DAK.js";
38
38
  import {
39
39
  caps,
40
40
  feedback,
@@ -44,7 +44,7 @@ import {
44
44
  makeTokens,
45
45
  sectionBox,
46
46
  signal
47
- } from "./chunk-UNAASSQ4.js";
47
+ } from "./chunk-FGHILN3D.js";
48
48
 
49
49
  // src/commands/work.ts
50
50
  import fs2 from "fs";
@@ -3,7 +3,7 @@ import {
3
3
  multiProjectFooter,
4
4
  requireConfig,
5
5
  resolveProjectScope
6
- } from "./chunk-JR6MKCC4.js";
6
+ } from "./chunk-MLTY3EE6.js";
7
7
  import {
8
8
  caps,
9
9
  generationsDir,
@@ -11,7 +11,7 @@ import {
11
11
  padEndDisplay,
12
12
  sectionBox,
13
13
  stringWidth
14
- } from "./chunk-UNAASSQ4.js";
14
+ } from "./chunk-FGHILN3D.js";
15
15
 
16
16
  // src/commands/metrics.ts
17
17
  import fs from "fs";
@@ -10,9 +10,10 @@ import {
10
10
  openFlow,
11
11
  promptNumber,
12
12
  selectMulti,
13
+ selectSingle,
13
14
  step,
14
15
  verifyStepLines
15
- } from "./chunk-7CPPZX6X.js";
16
+ } from "./chunk-SJG22DAK.js";
16
17
  import {
17
18
  caps,
18
19
  findProjectRoot,
@@ -22,7 +23,7 @@ import {
22
23
  makeSymbols,
23
24
  sectionBox,
24
25
  signal
25
- } from "./chunk-UNAASSQ4.js";
26
+ } from "./chunk-FGHILN3D.js";
26
27
 
27
28
  // src/commands/config.ts
28
29
  import fs from "fs";
@@ -136,6 +137,9 @@ function resolveProjectScope(cwd = process.cwd()) {
136
137
  return { mode: "single", projectRoot: root };
137
138
  }
138
139
  const registered = listRegisteredProjects().filter((p) => fs.existsSync(p.path));
140
+ if (registered.length === 1) {
141
+ return { mode: "single", projectRoot: registered[0]?.path };
142
+ }
139
143
  if (registered.length > 0) {
140
144
  return { mode: "multi", projects: registered };
141
145
  }
@@ -550,6 +554,11 @@ function renderConfig(config, c) {
550
554
  out.push(`${s.branch} \uC8FC \uC5B8\uC5B4 ${config.mainLanguage.join(", ") || "(\uC5C6\uC74C)"}`);
551
555
  out.push(`${s.branch} \uC131\uACA9 ${config.character || "(\uC5C6\uC74C)"}`);
552
556
  out.push(`${s.branch} \uC5D4\uC9C4 ${config.engineVersion}`);
557
+ const feedbackOn = config.feedback?.enabled ?? false;
558
+ out.push(`${s.branch} \uD53C\uB4DC\uBC31 ${feedbackOn ? "\uCF1C\uC9D0" : "\uAEBC\uC9D0"}`);
559
+ out.push(
560
+ `${s.vGuide} ${s.lastBranch} \uACBD\uB85C: ${color.dim(config.feedback?.path || `(\uAE30\uBCF8\uAC12) ${DEFAULT_FEEDBACK_PATH}`)}`
561
+ );
553
562
  out.push("");
554
563
  for (const k of VERIFY_ORDER) {
555
564
  const entry = config.verify[k];
@@ -573,7 +582,7 @@ function writeConfigFile(projectRoot, config) {
573
582
  fs.writeFileSync(p, `${JSON.stringify(config, null, 2)}
574
583
  `);
575
584
  }
576
- var EDIT_MENU = ["\uADF8\uB300\uB85C \uB454\uB2E4", "\uC8FC \uC5B8\uC5B4", "\uAC80\uC99D \uBA85\uB839\uC5B4", "\uC131\uACA9", "\uD504\uB85C\uC81D\uD2B8 \uC774\uB984"];
585
+ var EDIT_MENU = ["\uADF8\uB300\uB85C \uB454\uB2E4", "\uC8FC \uC5B8\uC5B4", "\uAC80\uC99D \uBA85\uB839\uC5B4", "\uC131\uACA9", "\uD504\uB85C\uC81D\uD2B8 \uC774\uB984", "\uD53C\uB4DC\uBC31 \uBAA8\uB4DC"];
577
586
  async function editVerifyCommands(rl, config, projectRoot, c, flow) {
578
587
  process.stdout.write(
579
588
  `${flowConnector(c)}
@@ -663,6 +672,54 @@ async function editProjectName(rl, config, projectRoot, c, flow) {
663
672
  });
664
673
  step(flow, outcome.message);
665
674
  }
675
+ async function editFeedback(rl, config, projectRoot, c, flow) {
676
+ const curEnabled = config.feedback?.enabled ?? false;
677
+ process.stdout.write(
678
+ `${flowConnector(c)}
679
+ ${flowActiveNode(
680
+ "\uD53C\uB4DC\uBC31 \uBAA8\uB4DC",
681
+ [
682
+ `\uD604\uC7AC: ${curEnabled ? "\uCF1C\uC9D0" : "\uAEBC\uC9D0"}`,
683
+ `\uACBD\uB85C: ${config.feedback?.path || `(\uAE30\uBCF8\uAC12) ${DEFAULT_FEEDBACK_PATH}`}`,
684
+ "",
685
+ "awl/awl-loop/awl-pipeline \uC2A4\uD0AC\xB7CLI \uC790\uCCB4\uC758 \uC124\uACC4 \uAC2D\xB7\uBC84\uADF8\xB7\uB9C8\uCC30\uC744 \uB2E4\uB978 \uD504\uB85C\uC81D\uD2B8\uB85C \uB77C\uC6B0\uD305\uD569\uB2C8\uB2E4."
686
+ ],
687
+ c
688
+ )}
689
+ `
690
+ );
691
+ const choice = await selectSingle(
692
+ rl,
693
+ ["\uCF1C\uC9D0", "\uAEBC\uC9D0"],
694
+ curEnabled ? 0 : 1,
695
+ c,
696
+ false,
697
+ "\uD53C\uB4DC\uBC31 \uBAA8\uB4DC"
698
+ );
699
+ const toggled = await applyConfigValue(
700
+ config,
701
+ projectRoot,
702
+ { kind: "feedback.enabled" },
703
+ choice === 0 ? "true" : "false",
704
+ { force: false }
705
+ );
706
+ step(flow, toggled.message);
707
+ const pathAnswer = (await ask(
708
+ rl,
709
+ `${flowConnector(c)} \uACBD\uB85C [${config.feedback?.path || DEFAULT_FEEDBACK_PATH}] (\uBE44\uC6B0\uBA74 \uADF8\uB300\uB85C, '-'\uBA74 \uAE30\uBCF8\uAC12): `
710
+ )).trim();
711
+ if (pathAnswer === "") {
712
+ return;
713
+ }
714
+ const outcome = await applyConfigValue(
715
+ config,
716
+ projectRoot,
717
+ { kind: "feedback.path" },
718
+ pathAnswer === "-" ? "" : pathAnswer,
719
+ { force: false }
720
+ );
721
+ step(flow, outcome.message);
722
+ }
666
723
  async function interactiveEditMenu(rl, config, projectRoot, c) {
667
724
  const flow = openFlow("\uC124\uC815 \uC218\uC815", c);
668
725
  process.stdout.write(`${flowConnector(c)}
@@ -685,6 +742,8 @@ ${flowActiveNode("\uC218\uC815\uD560 \uD56D\uBAA9\uC744 \uACE0\uB974\uC138\uC694
685
742
  await editCharacter(rl, config, projectRoot, c, flow);
686
743
  } else if (idx === 4) {
687
744
  await editProjectName(rl, config, projectRoot, c, flow);
745
+ } else if (idx === 5) {
746
+ await editFeedback(rl, config, projectRoot, c, flow);
688
747
  }
689
748
  closeFlow(flow);
690
749
  return true;
@@ -1,18 +1,16 @@
1
- import {
2
- WORKTREES_DIR
3
- } from "./chunk-JQV65R3M.js";
4
1
  import {
5
2
  readRecords
6
- } from "./chunk-QVP5DUND.js";
3
+ } from "./chunk-FK3Q7UY2.js";
7
4
  import {
8
5
  loadState
9
- } from "./chunk-UJ6CK5HC.js";
6
+ } from "./chunk-VE2GVNNS.js";
10
7
  import {
11
8
  multiProjectFooter,
12
9
  resolveProjectScope,
13
10
  run
14
- } from "./chunk-JR6MKCC4.js";
11
+ } from "./chunk-MLTY3EE6.js";
15
12
  import {
13
+ WORKTREES_DIR,
16
14
  caps,
17
15
  makeColors,
18
16
  makeSymbols,
@@ -22,7 +20,7 @@ import {
22
20
  signal,
23
21
  statusBadge,
24
22
  stringWidth
25
- } from "./chunk-UNAASSQ4.js";
23
+ } from "./chunk-FGHILN3D.js";
26
24
 
27
25
  // src/commands/status.ts
28
26
  import fs2 from "fs";
@@ -1,26 +1,26 @@
1
1
  import {
2
2
  protectedFilesMessage
3
- } from "./chunk-I3WXYD5C.js";
3
+ } from "./chunk-VVZOIFL4.js";
4
4
  import {
5
5
  gitDirtyFiles
6
- } from "./chunk-I5SS6HFR.js";
6
+ } from "./chunk-DQF7RF37.js";
7
7
  import {
8
8
  applyVerificationAttempts,
9
9
  loadState,
10
10
  writeState
11
- } from "./chunk-UJ6CK5HC.js";
11
+ } from "./chunk-VE2GVNNS.js";
12
12
  import {
13
13
  CommandNotFoundError,
14
14
  VERIFY_ORDER,
15
15
  requireConfig,
16
16
  run
17
- } from "./chunk-JR6MKCC4.js";
17
+ } from "./chunk-MLTY3EE6.js";
18
18
  import {
19
19
  caps,
20
20
  makeColors,
21
21
  sectionBox,
22
22
  signal
23
- } from "./chunk-UNAASSQ4.js";
23
+ } from "./chunk-FGHILN3D.js";
24
24
 
25
25
  // src/commands/verify.ts
26
26
  import fs from "fs";
@@ -9,6 +9,7 @@ import {
9
9
  flowStepLine,
10
10
  globalRoot,
11
11
  installedEngineVersion,
12
+ isInsideWorktreesDir,
12
13
  makeColors,
13
14
  makeSymbols,
14
15
  makeTokens,
@@ -18,7 +19,7 @@ import {
18
19
  sectionBox,
19
20
  signal,
20
21
  stringWidth
21
- } from "./chunk-UNAASSQ4.js";
22
+ } from "./chunk-FGHILN3D.js";
22
23
 
23
24
  // src/commands/init.ts
24
25
  import fs from "fs";
@@ -547,6 +548,9 @@ function installSafetyHook(projectRoot) {
547
548
  function registerProject(entry) {
548
549
  const raw = readJson(projectsFile());
549
550
  const list = Array.isArray(raw) ? raw : [];
551
+ if (isInsideWorktreesDir(entry.path)) {
552
+ return { count: list.length, skipped: true };
553
+ }
550
554
  const idx = list.findIndex((p) => p.path === entry.path);
551
555
  if (idx >= 0) {
552
556
  list[idx] = { ...list[idx], ...entry };
@@ -555,7 +559,7 @@ function registerProject(entry) {
555
559
  }
556
560
  writeFileEnsuringDir(projectsFile(), `${JSON.stringify(list, null, 2)}
557
561
  `);
558
- return list.length;
562
+ return { count: list.length, skipped: false };
559
563
  }
560
564
  function claudeSkillNames() {
561
565
  for (const base of [engineDir(), packageEngineDir()]) {
@@ -634,7 +638,7 @@ function syncExistingInstall(projectRoot, engineVersion, now) {
634
638
  `);
635
639
  configUpdated = true;
636
640
  }
637
- registerProject({
641
+ const { skipped: registrationSkipped } = registerProject({
638
642
  name: typeof raw?.project === "string" ? raw.project : path.basename(projectRoot),
639
643
  path: projectRoot,
640
644
  mainLanguage: Array.isArray(raw?.mainLanguage) ? raw.mainLanguage : [],
@@ -658,7 +662,7 @@ function syncExistingInstall(projectRoot, engineVersion, now) {
658
662
  { claude: skills.includes("claude"), codex: skills.includes("codex") },
659
663
  engineVersion
660
664
  );
661
- return { configUpdated, skills };
665
+ return { configUpdated, skills, registrationSkipped };
662
666
  }
663
667
  function countEntries(dir) {
664
668
  try {
@@ -691,7 +695,7 @@ function applyInit(projectRoot, inputs, now) {
691
695
  const statePath = writeState(projectRoot, now);
692
696
  const gitignore = ensureGitignore(projectRoot);
693
697
  const safetyHook = installSafetyHook(projectRoot);
694
- const projectCount = registerProject({
698
+ const { count: projectCount, skipped: registrationSkipped } = registerProject({
695
699
  name: inputs.project,
696
700
  path: projectRoot,
697
701
  mainLanguage: inputs.mainLanguage,
@@ -720,6 +724,7 @@ function applyInit(projectRoot, inputs, now) {
720
724
  gitignore,
721
725
  skills,
722
726
  projectCount,
727
+ registrationSkipped,
723
728
  ruleCount: countEntries(path.join(globalRoot(), "rules", "active")),
724
729
  lessonCount: countEntries(path.join(globalRoot(), "lessons")),
725
730
  safetyHook
@@ -785,6 +790,13 @@ function resultSetupLines(result, c) {
785
790
  `\uADDC\uCE59 ${result.ruleCount}\uAC1C \xB7 \uAD50\uD6C8 ${result.lessonCount}\uAC1C \xB7 \uB4F1\uB85D\uB41C \uD504\uB85C\uC81D\uD2B8 ${result.projectCount}\uAC1C \xB7 1\uC138\uB300`
786
791
  )
787
792
  );
793
+ if (result.registrationSkipped) {
794
+ setupLines.push(
795
+ color.dim(
796
+ "\uC774 \uC704\uCE58\uB294 \uB808\uC778 \uC6CC\uD06C\uD2B8\uB9AC\uC785\uB2C8\uB2E4(.awl-worktrees \uD558\uC704) \u2014 \uC804\uC5ED \uD504\uB85C\uC81D\uD2B8 \uBAA9\uB85D\uC5D0\uB294 \uB4F1\uB85D\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uBD80\uBAA8 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C awl lane rm/awl remove\uB85C \uAD00\uB9AC\uD558\uC138\uC694."
797
+ )
798
+ );
799
+ }
788
800
  return setupLines;
789
801
  }
790
802
  function resultNextLines(inputs, c) {
@@ -1155,6 +1167,13 @@ ${flowActiveNode("\uAE30\uC874 \uC124\uC815", summaryLines, c)}
1155
1167
  } else {
1156
1168
  process.stdout.write("\n \uC124\uC815\uC744 \uADF8\uB300\uB85C \uC501\uB2C8\uB2E4. \uC774\uBBF8 \uCD5C\uC2E0\uC785\uB2C8\uB2E4.\n");
1157
1169
  }
1170
+ if (synced.registrationSkipped) {
1171
+ process.stdout.write(
1172
+ `
1173
+ ${makeColors(c.color).dim("\uC774 \uC704\uCE58\uB294 \uB808\uC778 \uC6CC\uD06C\uD2B8\uB9AC\uC785\uB2C8\uB2E4(.awl-worktrees \uD558\uC704) \u2014 \uC804\uC5ED \uD504\uB85C\uC81D\uD2B8 \uBAA9\uB85D\uC5D0\uB294 \uB4F1\uB85D\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uBD80\uBAA8 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C awl lane rm/awl remove\uB85C \uAD00\uB9AC\uD558\uC138\uC694.")}
1174
+ `
1175
+ );
1176
+ }
1158
1177
  return;
1159
1178
  }
1160
1179
  if (choice === 1) {
@@ -1330,12 +1349,14 @@ async function runInit(opts) {
1330
1349
  const synced = syncExistingInstall(projectRoot, engine.engineVersion, now);
1331
1350
  const syncNote = synced.configUpdated || synced.skills.length > 0 ? `
1332
1351
  ${signal(c, "ok")} \uBC84\uC804 \uB9C8\uCEE4\uB97C ${engine.engineVersion} \uB85C \uB3D9\uAE30\uD654\uD588\uC2B5\uB2C8\uB2E4${synced.skills.length ? ` (\uC2A4\uD0AC: ${synced.skills.join(", ")})` : ""}.` : "";
1352
+ const worktreeNote = synced.registrationSkipped ? `
1353
+ ${makeColors(c.color).dim("\uC774 \uC704\uCE58\uB294 \uB808\uC778 \uC6CC\uD06C\uD2B8\uB9AC\uC785\uB2C8\uB2E4(.awl-worktrees \uD558\uC704) \u2014 \uC804\uC5ED \uD504\uB85C\uC81D\uD2B8 \uBAA9\uB85D\uC5D0\uB294 \uB4F1\uB85D\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uBD80\uBAA8 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C awl lane rm/awl remove\uB85C \uAD00\uB9AC\uD558\uC138\uC694.")}` : "";
1333
1354
  process.stdout.write(
1334
1355
  `
1335
1356
  .awl/config.json \uC774 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4. \uADF8\uB300\uB85C \uC501\uB2C8\uB2E4.
1336
1357
  ${signal(c, "ok")} \uC5D4\uC9C4 \uD15C\uD50C\uB9BF\uC744 ${engine.created ? "\uC124\uCE58\uD588\uC2B5\uB2C8\uB2E4." : "\uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4."}${syncNote}${hook.warning ? `
1337
1358
  ${signal(c, "warn")} ${hook.warning}` : hook.installed ? `
1338
- ${signal(c, "ok")} git push \uCC28\uB2E8 \uD6C5 \uC124\uCE58` : ""}
1359
+ ${signal(c, "ok")} git push \uCC28\uB2E8 \uD6C5 \uC124\uCE58` : ""}${worktreeNote}
1339
1360
  `
1340
1361
  );
1341
1362
  return;
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  resolveProjectRoot
3
- } from "./chunk-JR6MKCC4.js";
3
+ } from "./chunk-MLTY3EE6.js";
4
4
  import {
5
5
  caps,
6
6
  makeColors,
7
7
  sectionBox
8
- } from "./chunk-UNAASSQ4.js";
8
+ } from "./chunk-FGHILN3D.js";
9
9
 
10
10
  // src/commands/state.ts
11
11
  import fs from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  run
3
- } from "./chunk-JR6MKCC4.js";
3
+ } from "./chunk-MLTY3EE6.js";
4
4
 
5
5
  // src/core/protected-files.ts
6
6
  async function changedProtectedFiles(projectRoot, protectedFiles) {