agent-work-loop 0.6.31 → 0.6.34
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.md +6 -0
- package/dist/{brief-ZZSQ6RQS.js → brief-2UCDBAB6.js} +5 -5
- package/dist/{changelog-JWLVVHZL.js → changelog-AICBEFUV.js} +5 -5
- package/dist/{chunk-SV4D72NX.js → chunk-3R52QFNQ.js} +2 -2
- package/dist/{chunk-Q7V3WVKT.js → chunk-4Q4FDZXN.js} +4 -4
- package/dist/{chunk-RNZCRXE3.js → chunk-EPVWUYXP.js} +5 -5
- package/dist/{chunk-2DAP3QBU.js → chunk-N5QEEXCO.js} +231 -129
- package/dist/{chunk-7NOHUUXV.js → chunk-O7V4DHPZ.js} +73 -12
- package/dist/{chunk-DIRYW77S.js → chunk-QFHXKTV6.js} +5 -5
- package/dist/{chunk-RRQYSRRT.js → chunk-RG6FT7I2.js} +5 -5
- package/dist/{chunk-3UPF7LZT.js → chunk-SDNJULFU.js} +5 -5
- package/dist/{chunk-45X7T64Y.js → chunk-SUF5ISJM.js} +63 -20
- package/dist/{chunk-JPFGMDQ4.js → chunk-SZQNXMYU.js} +62 -42
- package/dist/{chunk-22SUY5RE.js → chunk-TUV6NSTM.js} +6 -6
- package/dist/{chunk-77EZYCLF.js → chunk-VKLSQMAW.js} +2 -2
- package/dist/{chunk-5APWNDRG.js → chunk-VR74OBHK.js} +2 -2
- package/dist/{chunk-TTZY2GLK.js → chunk-W2AMCPKI.js} +1 -1
- package/dist/{chunk-Z3QCPOOA.js → chunk-WL674RWY.js} +2 -2
- package/dist/{chunk-YP4VCWPV.js → chunk-WPZK7LJU.js} +3 -3
- package/dist/cli.js +122 -51
- package/dist/{commit-3UZE7XJM.js → commit-PQE62KLZ.js} +6 -6
- package/dist/{config-DAD4LIWR.js → config-LHWI2J4M.js} +3 -3
- package/dist/{doctor-AW65MZKN.js → doctor-MEYI2ROW.js} +8 -8
- package/dist/{evolve-K4WKRA6U.js → evolve-KSUWIZCY.js} +7 -7
- package/dist/{feedback-3C33YHKF.js → feedback-633KAKEZ.js} +5 -5
- package/dist/{gotchas-IGEQILOO.js → gotchas-R236D2U2.js} +7 -7
- package/dist/{hold-recheck-THSJKF5G.js → hold-recheck-7D47ITAP.js} +16 -16
- package/dist/{init-MRJEU7IR.js → init-U7F6ECXI.js} +12 -2
- package/dist/lane-2OZBXFKL.js +41 -0
- package/dist/{loop-summary-MPEKQ2EC.js → loop-summary-HBADJTOZ.js} +6 -6
- package/dist/{metrics-64WBBQQX.js → metrics-WI2GOPGG.js} +4 -4
- package/dist/{record-GAWMF7KL.js → record-CEEEHNNF.js} +5 -5
- package/dist/{remove-ELP4MFVE.js → remove-GWSIRW36.js} +25 -15
- package/dist/{review-A5Q7NSOD.js → review-F6Y2TD5B.js} +13 -13
- package/dist/{rules-BEQT7YVN.js → rules-A7YTU3HV.js} +8 -8
- package/dist/{state-RDKIOU25.js → state-KHZNSJRS.js} +4 -4
- package/dist/status-HU3RLDSB.js +40 -0
- package/dist/{update-7RQQJ2TH.js → update-7BLNEJ52.js} +5 -5
- package/dist/{verify-UUJ6KD37.js → verify-WJNFIF4Y.js} +10 -10
- package/dist/version-check-DFNWGNLY.js +14 -0
- package/dist/work-LDPAHEPH.js +60 -0
- package/engine/version.json +1 -1
- package/package.json +1 -1
- package/dist/lane-ZQVD7EDE.js +0 -41
- package/dist/status-FP73XOZS.js +0 -40
- package/dist/version-check-H2T3WW3I.js +0 -14
- package/dist/work-HWJSUWBR.js +0 -50
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
caps,
|
|
3
3
|
engineDir,
|
|
4
|
+
flowActiveNode,
|
|
5
|
+
flowClose,
|
|
6
|
+
flowConnector,
|
|
7
|
+
flowOpen,
|
|
8
|
+
flowSelectLine,
|
|
9
|
+
flowStepLine,
|
|
4
10
|
globalRoot,
|
|
5
11
|
installedEngineVersion,
|
|
6
12
|
makeColors,
|
|
@@ -12,7 +18,7 @@ import {
|
|
|
12
18
|
sectionBox,
|
|
13
19
|
signal,
|
|
14
20
|
stringWidth
|
|
15
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-SUF5ISJM.js";
|
|
16
22
|
|
|
17
23
|
// src/commands/init.ts
|
|
18
24
|
import fs from "fs";
|
|
@@ -107,14 +113,21 @@ function moveCursorUp(n) {
|
|
|
107
113
|
}
|
|
108
114
|
function renderInteractiveSelect(options, state, multi, c, presentation) {
|
|
109
115
|
const color = makeColors(c.color);
|
|
110
|
-
const lines =
|
|
116
|
+
const lines = [];
|
|
117
|
+
if (presentation.body && presentation.body.length > 0) {
|
|
118
|
+
lines.push(...presentation.body, "");
|
|
119
|
+
}
|
|
120
|
+
lines.push(...renderSelectOptions(options, state, multi, c).split("\n"));
|
|
111
121
|
if (presentation.hint) {
|
|
112
122
|
lines.push("");
|
|
113
123
|
lines.push(color.dim(presentation.hint));
|
|
114
124
|
}
|
|
115
|
-
const text =
|
|
125
|
+
const text = flowActiveNode(presentation.title ?? "\uC120\uD0DD", lines, c);
|
|
116
126
|
return { text, lineCount: text.split("\n").length };
|
|
117
127
|
}
|
|
128
|
+
function clearFrame(n) {
|
|
129
|
+
return n > 0 ? `${moveCursorUp(n)}\x1B[0J` : "";
|
|
130
|
+
}
|
|
118
131
|
async function runInteractiveSelect(options, defaultIndex, multi, c, defaultChecked = [], presentation = {}) {
|
|
119
132
|
let state = initSelectState(defaultIndex, defaultChecked);
|
|
120
133
|
process.stdin.setRawMode(true);
|
|
@@ -134,9 +147,45 @@ async function runInteractiveSelect(options, defaultIndex, multi, c, defaultChec
|
|
|
134
147
|
process.stdin.setRawMode(false);
|
|
135
148
|
process.stdin.pause();
|
|
136
149
|
}
|
|
150
|
+
process.stdout.write(clearFrame(rendered.lineCount));
|
|
137
151
|
return state.cancelled ? null : { index: state.index, checked: [...state.checked] };
|
|
138
152
|
}
|
|
139
153
|
|
|
154
|
+
// src/core/flow.ts
|
|
155
|
+
function openFlow(title, c) {
|
|
156
|
+
process.stdout.write(`${flowOpen(title, c)}
|
|
157
|
+
`);
|
|
158
|
+
return { c };
|
|
159
|
+
}
|
|
160
|
+
function step(session, title) {
|
|
161
|
+
process.stdout.write(`${flowConnector(session.c)}
|
|
162
|
+
${flowStepLine(title, session.c)}
|
|
163
|
+
`);
|
|
164
|
+
}
|
|
165
|
+
function selectStep(session, title) {
|
|
166
|
+
process.stdout.write(`${flowConnector(session.c)}
|
|
167
|
+
${flowSelectLine(title, session.c)}
|
|
168
|
+
`);
|
|
169
|
+
}
|
|
170
|
+
async function activeSelect(session, options, defaultIndex, multi, defaultChecked = [], presentation = {}) {
|
|
171
|
+
process.stdout.write(`${flowConnector(session.c)}
|
|
172
|
+
`);
|
|
173
|
+
const result = await runInteractiveSelect(
|
|
174
|
+
options,
|
|
175
|
+
defaultIndex,
|
|
176
|
+
multi,
|
|
177
|
+
session.c,
|
|
178
|
+
defaultChecked,
|
|
179
|
+
presentation
|
|
180
|
+
);
|
|
181
|
+
process.stdout.write("\x1B[1A\x1B[0J");
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
function closeFlow(session) {
|
|
185
|
+
process.stdout.write(`${flowClose(session.c)}
|
|
186
|
+
`);
|
|
187
|
+
}
|
|
188
|
+
|
|
140
189
|
// src/commands/init.ts
|
|
141
190
|
function exists(p) {
|
|
142
191
|
try {
|
|
@@ -576,7 +625,7 @@ function writeSkillsVersionStamp(projectRoot, installed, engineVersion) {
|
|
|
576
625
|
fs.writeFileSync(p, `${JSON.stringify(next, null, 2)}
|
|
577
626
|
`);
|
|
578
627
|
}
|
|
579
|
-
function syncExistingInstall(projectRoot, engineVersion) {
|
|
628
|
+
function syncExistingInstall(projectRoot, engineVersion, now) {
|
|
580
629
|
let configUpdated = false;
|
|
581
630
|
const configPath = path.join(projectRoot, ".awl", "config.json");
|
|
582
631
|
const raw = readJson(configPath);
|
|
@@ -585,6 +634,13 @@ function syncExistingInstall(projectRoot, engineVersion) {
|
|
|
585
634
|
`);
|
|
586
635
|
configUpdated = true;
|
|
587
636
|
}
|
|
637
|
+
registerProject({
|
|
638
|
+
name: typeof raw?.project === "string" ? raw.project : path.basename(projectRoot),
|
|
639
|
+
path: projectRoot,
|
|
640
|
+
mainLanguage: Array.isArray(raw?.mainLanguage) ? raw.mainLanguage : [],
|
|
641
|
+
character: typeof raw?.character === "string" ? raw.character : "",
|
|
642
|
+
registeredAt: now
|
|
643
|
+
});
|
|
588
644
|
const skills = [];
|
|
589
645
|
const claudeInUse = claudeSkillNames().some(
|
|
590
646
|
(name) => exists(path.join(projectRoot, ".claude", "skills", name))
|
|
@@ -670,8 +726,8 @@ function applyInit(projectRoot, inputs, now) {
|
|
|
670
726
|
};
|
|
671
727
|
}
|
|
672
728
|
var WIDTH = 64;
|
|
673
|
-
function stepBox(
|
|
674
|
-
return sectionBox(`${
|
|
729
|
+
function stepBox(step2, title, lines, c) {
|
|
730
|
+
return sectionBox(`${step2}${c.unicode ? " \xB7 " : " - "}${title}`, lines, c, WIDTH - 4);
|
|
675
731
|
}
|
|
676
732
|
var VERIFY_LABELS = {
|
|
677
733
|
typecheck: "\uD0C0\uC785\uCCB4\uD06C",
|
|
@@ -709,7 +765,7 @@ function renderNonTtyNotice() {
|
|
|
709
765
|
""
|
|
710
766
|
].join("\n");
|
|
711
767
|
}
|
|
712
|
-
function
|
|
768
|
+
function resultSetupLines(result, c) {
|
|
713
769
|
const color = makeColors(c.color);
|
|
714
770
|
const t = makeTokens(c);
|
|
715
771
|
const line = (name, value, note = "") => ` ${padEndDisplay(name, 20)}${t.emphasis(value)}${note ? ` ${color.dim(note)}` : ""}`;
|
|
@@ -729,6 +785,10 @@ function renderResult(result, inputs, c) {
|
|
|
729
785
|
`\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`
|
|
730
786
|
)
|
|
731
787
|
);
|
|
788
|
+
return setupLines;
|
|
789
|
+
}
|
|
790
|
+
function resultNextLines(inputs, c) {
|
|
791
|
+
const color = makeColors(c.color);
|
|
732
792
|
const nextLines = [];
|
|
733
793
|
if (inputs.skills.claude) {
|
|
734
794
|
nextLines.push("Claude Code \uB97C \uC5F4\uACE0 \uC774\uB807\uAC8C \uB9D0\uD558\uC138\uC694.");
|
|
@@ -741,13 +801,26 @@ function renderResult(result, inputs, c) {
|
|
|
741
801
|
} else {
|
|
742
802
|
nextLines.push("\uB098\uC911\uC5D0 \uC2A4\uD0AC\uC744 \uC124\uCE58\uD558\uB824\uBA74 awl init \uC744 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.");
|
|
743
803
|
}
|
|
804
|
+
return nextLines;
|
|
805
|
+
}
|
|
806
|
+
function renderResult(result, inputs, c) {
|
|
744
807
|
return [
|
|
745
808
|
"",
|
|
746
|
-
sectionBox("\uC124\uC815 \uC644\uB8CC",
|
|
809
|
+
sectionBox("\uC124\uC815 \uC644\uB8CC", resultSetupLines(result, c), c, WIDTH - 4),
|
|
747
810
|
"",
|
|
748
|
-
sectionBox("\uB2E4\uC74C \uB2E8\uACC4",
|
|
811
|
+
sectionBox("\uB2E4\uC74C \uB2E8\uACC4", resultNextLines(inputs, c), c, WIDTH - 4)
|
|
749
812
|
].join("\n");
|
|
750
813
|
}
|
|
814
|
+
function commitResultFlow(session, result, inputs, c) {
|
|
815
|
+
for (const line of resultSetupLines(result, c)) {
|
|
816
|
+
step(session, line);
|
|
817
|
+
}
|
|
818
|
+
step(session, "\uB2E4\uC74C \uB2E8\uACC4");
|
|
819
|
+
for (const line of resultNextLines(inputs, c)) {
|
|
820
|
+
process.stdout.write(`${flowConnector(c)} ${line}
|
|
821
|
+
`);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
751
824
|
var LANG_OPTIONS = ["TypeScript", "JavaScript", "Python", "\uC9C1\uC811 \uC785\uB825"];
|
|
752
825
|
var LANG_VALUES = ["typescript", "javascript", "python", ""];
|
|
753
826
|
function langDefaultIndices(projectRoot) {
|
|
@@ -760,10 +833,19 @@ function langDefaultIndices(projectRoot) {
|
|
|
760
833
|
}
|
|
761
834
|
function buildScreens(projectRoot, hasGlobal, c) {
|
|
762
835
|
const project = path.basename(projectRoot);
|
|
763
|
-
const defLangIndices = langDefaultIndices(projectRoot);
|
|
764
836
|
const verify = detectVerify(projectRoot);
|
|
765
837
|
const agents = detectAgents(projectRoot);
|
|
766
|
-
const welcome = hasGlobal ? null :
|
|
838
|
+
const welcome = hasGlobal ? null : welcomeLines(project, projectRoot).join("\n");
|
|
839
|
+
return {
|
|
840
|
+
welcome,
|
|
841
|
+
lang: stepBox("1/3", "\uC8FC \uC5B8\uC5B4", langScreenLines(projectRoot), c),
|
|
842
|
+
verify: stepBox("2/3", "\uAC80\uC99D \uBA85\uB839\uC5B4", verifyStepLines(verify), c),
|
|
843
|
+
character: stepBox("3/3", "\uADDC\uCE59\uACFC \uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uC131\uACA9", characterScreenLines(), c),
|
|
844
|
+
skills: stepBox("\uC2A4\uD0AC", "\uC2A4\uD0AC \uC124\uCE58", skillsScreenLines(agents), c)
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
function welcomeLines(project, projectRoot) {
|
|
848
|
+
return [
|
|
767
849
|
"",
|
|
768
850
|
" ~/.awl \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uCC98\uC74C \uC624\uC168\uAD70\uC694.",
|
|
769
851
|
"",
|
|
@@ -776,46 +858,38 @@ function buildScreens(projectRoot, hasGlobal, c) {
|
|
|
776
858
|
" \uB2E4\uB978 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C\uB3C4 awl init \uC744 \uC2E4\uD589\uD558\uBA74 \uADF8\uB54C \uB4F1\uB85D\uB429\uB2C8\uB2E4.",
|
|
777
859
|
" \uADDC\uCE59\uACFC \uAD50\uD6C8\uC740 \uD504\uB85C\uC81D\uD2B8\uAC00 \uC544\uB2C8\uB77C \uB2F9\uC2E0\uC5D0\uAC8C \uC313\uC774\uACE0,",
|
|
778
860
|
" \uB4F1\uB85D\uB41C \uBAA8\uB4E0 \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C \uD568\uAED8 \uC4F0\uC785\uB2C8\uB2E4."
|
|
779
|
-
]
|
|
861
|
+
];
|
|
862
|
+
}
|
|
863
|
+
function langScreenLines(projectRoot) {
|
|
864
|
+
const defLangIndices = langDefaultIndices(projectRoot);
|
|
780
865
|
const detectedLangLabels = defLangIndices.map((i) => LANG_OPTIONS[i] ?? "TypeScript").join(", ");
|
|
781
|
-
|
|
866
|
+
return [
|
|
782
867
|
`\uC790\uB3D9 \uAC10\uC9C0: ${detectedLangLabels || "TypeScript"}`,
|
|
783
868
|
"",
|
|
784
869
|
"\uC5EC\uB7EC \uAC1C\uB97C \uC4F0\uB294 \uD504\uB85C\uC81D\uD2B8\uBA74(\uC608: TypeScript \uD504\uB860\uD2B8 + Python \uBC31\uC5D4\uB4DC) \uC804\uBD80 \uACE0\uB974\uC138\uC694.",
|
|
785
870
|
"\u2191\u2193 \uB610\uB294 j/k \uB85C \uC774\uB3D9, Space \uB85C \uC120\uD0DD, Enter \uB85C \uD655\uC815\uD558\uC138\uC694.",
|
|
786
871
|
"\uD0A4 \uC785\uB825\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD130\uBBF8\uB110\uC5D0\uC11C\uB294 \uBC88\uD638\uB97C \uC27C\uD45C\uB85C \uC785\uB825\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
|
|
787
872
|
];
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
[
|
|
809
|
-
"awl \uC740 \uD310\uB2E8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD30C\uC77C\uACFC \uC0C1\uD0DC\uB9CC \uAD00\uB9AC\uD569\uB2C8\uB2E4.",
|
|
810
|
-
"\uD310\uB2E8\uC740 \uC774\uBBF8 \uC4F0\uACE0 \uACC4\uC2E0 \uC5D0\uC774\uC804\uD2B8\uAC00 \uD569\uB2C8\uB2E4.",
|
|
811
|
-
"",
|
|
812
|
-
"\uBC14\uB85C \uC544\uB798\uC5D0\uC11C \uC124\uCE58\uD560 \uC5D0\uC774\uC804\uD2B8\uB97C \uACE0\uB985\uB2C8\uB2E4.",
|
|
813
|
-
"\uCCAB \uBC88\uC9F8 \u201C\uBAA8\uB450 \uC124\uCE58\u201D\uB97C \uACE0\uB974\uAC70\uB098, Space \uB85C \uD544\uC694\uD55C \uD56D\uBAA9\uB9CC \uACE0\uB97C \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
814
|
-
`\uAC10\uC9C0\uB428: Claude Code ${agents.claude ? "\uC788\uC74C" : "\uC5C6\uC74C"} \xB7 Codex ${agents.codex ? "\uC788\uC74C" : "\uC5C6\uC74C"}`
|
|
815
|
-
],
|
|
816
|
-
c
|
|
817
|
-
)
|
|
818
|
-
};
|
|
873
|
+
}
|
|
874
|
+
function characterScreenLines() {
|
|
875
|
+
return [
|
|
876
|
+
"\uAC19\uC740 \uC2E4\uD328\uAC00 \uC313\uC774\uBA74 \uADDC\uCE59\uC774 \uB418\uACE0, \uB2E4\uC74C \uD504\uB85C\uC81D\uD2B8\uC5D0\uB3C4 \uC804\uD30C\uB429\uB2C8\uB2E4.",
|
|
877
|
+
"\uD504\uB85C\uC81D\uD2B8\uC758 \uC131\uACA9\uC740 \uADF8 \uADDC\uCE59\uC744 \uC5EC\uAE30\uC5D0\uB3C4 \uC801\uC6A9\uD560\uC9C0 \uD310\uB2E8\uD558\uB294 \uADFC\uAC70\uC785\uB2C8\uB2E4.",
|
|
878
|
+
"",
|
|
879
|
+
"\uC774 \uD504\uB85C\uC81D\uD2B8\uB294 \uC5B4\uB5A4 \uACF3\uC785\uB2C8\uAE4C?",
|
|
880
|
+
'(\uC608\uC2DC: "React + TailwindCSS \uC6F9 \uD504\uB860\uD2B8\uC5D4\uB4DC", "Python Fast API \uBD84\uC11D \uC11C\uBC84",',
|
|
881
|
+
' "TypeScript \uB77C\uC774\uBE0C\uB7EC\uB9AC \uD328\uD0A4\uC9C0")'
|
|
882
|
+
];
|
|
883
|
+
}
|
|
884
|
+
function skillsScreenLines(agents) {
|
|
885
|
+
return [
|
|
886
|
+
"awl \uC740 \uD310\uB2E8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD30C\uC77C\uACFC \uC0C1\uD0DC\uB9CC \uAD00\uB9AC\uD569\uB2C8\uB2E4.",
|
|
887
|
+
"\uD310\uB2E8\uC740 \uC774\uBBF8 \uC4F0\uACE0 \uACC4\uC2E0 \uC5D0\uC774\uC804\uD2B8\uAC00 \uD569\uB2C8\uB2E4.",
|
|
888
|
+
"",
|
|
889
|
+
"\uBC14\uB85C \uC544\uB798\uC5D0\uC11C \uC124\uCE58\uD560 \uC5D0\uC774\uC804\uD2B8\uB97C \uACE0\uB985\uB2C8\uB2E4.",
|
|
890
|
+
"\uCCAB \uBC88\uC9F8 \u201C\uBAA8\uB450 \uC124\uCE58\u201D\uB97C \uACE0\uB974\uAC70\uB098, Space \uB85C \uD544\uC694\uD55C \uD56D\uBAA9\uB9CC \uACE0\uB97C \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
891
|
+
`\uAC10\uC9C0\uB428: Claude Code ${agents.claude ? "\uC788\uC74C" : "\uC5C6\uC74C"} \xB7 Codex ${agents.codex ? "\uC788\uC74C" : "\uC5C6\uC74C"}`
|
|
892
|
+
];
|
|
819
893
|
}
|
|
820
894
|
function ask(rl, q) {
|
|
821
895
|
return new Promise((resolve) => rl.question(q, (a) => resolve(a)));
|
|
@@ -903,7 +977,6 @@ function applyVerifyCwd(verify, cwd) {
|
|
|
903
977
|
return verify;
|
|
904
978
|
}
|
|
905
979
|
async function interactiveInputs(projectRoot, hasGlobal, c) {
|
|
906
|
-
const screens = buildScreens(projectRoot, hasGlobal, c);
|
|
907
980
|
const project = path.basename(projectRoot);
|
|
908
981
|
const useRawMode = rawModeCapable();
|
|
909
982
|
const session = { rl: null };
|
|
@@ -913,29 +986,48 @@ async function interactiveInputs(projectRoot, hasGlobal, c) {
|
|
|
913
986
|
}
|
|
914
987
|
return session.rl;
|
|
915
988
|
};
|
|
989
|
+
const flow = openFlow("awl init", c);
|
|
916
990
|
try {
|
|
917
|
-
if (
|
|
918
|
-
process.stdout.write(`${
|
|
991
|
+
if (!hasGlobal) {
|
|
992
|
+
process.stdout.write(`${flowConnector(c)}
|
|
919
993
|
`);
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
${screens.lang}
|
|
923
|
-
|
|
994
|
+
for (const line of welcomeLines(project, projectRoot)) {
|
|
995
|
+
process.stdout.write(`${flowConnector(c)}${line}
|
|
924
996
|
`);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
925
999
|
const defaultLangChecked = langDefaultIndices(projectRoot);
|
|
926
|
-
const
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1000
|
+
const langBody = langScreenLines(projectRoot);
|
|
1001
|
+
let langChecked;
|
|
1002
|
+
if (useRawMode) {
|
|
1003
|
+
const r = await activeSelect(flow, LANG_OPTIONS, 0, true, defaultLangChecked, {
|
|
1004
|
+
title: "\uC8FC \uC5B8\uC5B4",
|
|
1005
|
+
body: langBody,
|
|
1006
|
+
hint: "\u2191\u2193 \uB610\uB294 j/k \uC774\uB3D9 \xB7 Space \uC120\uD0DD \xB7 Enter \uD655\uC815 \xB7 Esc \uAE30\uBCF8\uAC12 \uC720\uC9C0"
|
|
1007
|
+
});
|
|
1008
|
+
langChecked = r?.checked ?? defaultLangChecked;
|
|
1009
|
+
} else {
|
|
1010
|
+
process.stdout.write(`${flowConnector(c)}
|
|
1011
|
+
${flowActiveNode("\uC8FC \uC5B8\uC5B4", langBody, c)}
|
|
1012
|
+
`);
|
|
1013
|
+
langChecked = await selectMulti(
|
|
1014
|
+
prompt(),
|
|
1015
|
+
LANG_OPTIONS,
|
|
1016
|
+
defaultLangChecked,
|
|
1017
|
+
c,
|
|
1018
|
+
false,
|
|
1019
|
+
"\uC8FC \uC5B8\uC5B4"
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
931
1022
|
const manualLangIdx = LANG_OPTIONS.length - 1;
|
|
932
1023
|
const mainLanguage = langChecked.filter((i) => i !== manualLangIdx).map((i) => LANG_VALUES[i]).filter((v) => typeof v === "string" && v !== "");
|
|
933
1024
|
if (langChecked.includes(manualLangIdx)) {
|
|
934
|
-
const typed = (await ask(prompt(),
|
|
1025
|
+
const typed = (await ask(prompt(), `${flowConnector(c)} \uC8FC \uC5B8\uC5B4\uB97C \uC785\uB825\uD558\uC138\uC694: `)).trim();
|
|
935
1026
|
if (typed) {
|
|
936
1027
|
mainLanguage.push(typed);
|
|
937
1028
|
}
|
|
938
1029
|
}
|
|
1030
|
+
selectStep(flow, `\uC8FC \uC5B8\uC5B4: ${mainLanguage.length > 0 ? mainLanguage.join(", ") : "(\uC5C6\uC74C)"}`);
|
|
939
1031
|
const rootVerify = detectVerify(projectRoot);
|
|
940
1032
|
const located = await promptVerifyLocation(
|
|
941
1033
|
prompt(),
|
|
@@ -944,35 +1036,26 @@ ${screens.lang}
|
|
|
944
1036
|
makeColors(c.color)
|
|
945
1037
|
);
|
|
946
1038
|
const verify = located.verify;
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
${
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
} else {
|
|
953
|
-
process.stdout.write(`
|
|
954
|
-
${screens.verify}
|
|
955
|
-
|
|
956
|
-
`);
|
|
957
|
-
}
|
|
1039
|
+
process.stdout.write(
|
|
1040
|
+
`${flowConnector(c)}
|
|
1041
|
+
${flowActiveNode("\uAC80\uC99D \uBA85\uB839\uC5B4", verifyStepLines(verify), c)}
|
|
1042
|
+
`
|
|
1043
|
+
);
|
|
958
1044
|
for (const k of Object.keys(VERIFY_LABELS)) {
|
|
959
1045
|
const cur = verify[k];
|
|
960
1046
|
const shown = cur ? cur.cmd : "(\uC5C6\uC74C)";
|
|
961
|
-
const answer = (await ask(prompt(),
|
|
1047
|
+
const answer = (await ask(prompt(), `${flowConnector(c)} ${VERIFY_LABELS[k]} [${shown}]: `)).trim();
|
|
962
1048
|
if (answer !== "") {
|
|
963
1049
|
verify[k] = answer.toLowerCase() === "\uC5C6\uC74C" || answer === "-" ? null : splitEnv(answer);
|
|
964
1050
|
}
|
|
965
1051
|
}
|
|
966
1052
|
applyVerifyCwd(verify, located.cwd);
|
|
967
|
-
process.stdout.write(
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
`
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
${screens.skills}
|
|
974
|
-
|
|
975
|
-
`);
|
|
1053
|
+
process.stdout.write(
|
|
1054
|
+
`${flowConnector(c)}
|
|
1055
|
+
${flowActiveNode("\uADDC\uCE59\uACFC \uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uC131\uACA9", characterScreenLines(), c)}
|
|
1056
|
+
`
|
|
1057
|
+
);
|
|
1058
|
+
const character = (await ask(prompt(), `${flowConnector(c)} > `)).trim();
|
|
976
1059
|
const agents = detectAgents(projectRoot);
|
|
977
1060
|
const skillOptions = [
|
|
978
1061
|
"\uBAA8\uB450 \uC124\uCE58 (Claude Code + Codex)",
|
|
@@ -984,26 +1067,39 @@ ${screens.skills}
|
|
|
984
1067
|
session.rl.close();
|
|
985
1068
|
session.rl = null;
|
|
986
1069
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
defaultChecked
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1070
|
+
let checked;
|
|
1071
|
+
if (useRawMode) {
|
|
1072
|
+
const r = await activeSelect(flow, skillOptions, 0, true, defaultChecked, {
|
|
1073
|
+
title: "\uC124\uCE58\uD560 \uC5D0\uC774\uC804\uD2B8 \uC2A4\uD0AC",
|
|
1074
|
+
body: skillsScreenLines(agents),
|
|
1075
|
+
hint: "\u2191\u2193 \uB610\uB294 j/k \uC774\uB3D9 \xB7 Space \uC120\uD0DD \xB7 Enter \uD655\uC815 \xB7 Esc \uAE30\uBCF8\uAC12 \uC720\uC9C0",
|
|
1076
|
+
selectAllIndex: 0
|
|
1077
|
+
});
|
|
1078
|
+
checked = r?.checked ?? defaultChecked;
|
|
1079
|
+
} else {
|
|
1080
|
+
process.stdout.write(
|
|
1081
|
+
`${flowConnector(c)}
|
|
1082
|
+
${flowActiveNode("\uC124\uCE58\uD560 \uC5D0\uC774\uC804\uD2B8 \uC2A4\uD0AC", skillsScreenLines(agents), c)}
|
|
1083
|
+
`
|
|
1084
|
+
);
|
|
1085
|
+
checked = await selectMulti(
|
|
1086
|
+
prompt(),
|
|
1087
|
+
skillOptions,
|
|
1088
|
+
defaultChecked,
|
|
1089
|
+
c,
|
|
1090
|
+
false,
|
|
1091
|
+
"\uC124\uCE58\uD560 \uC5D0\uC774\uC804\uD2B8 \uC2A4\uD0AC",
|
|
1092
|
+
0
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1001
1095
|
const installAll = checked.includes(0);
|
|
1002
1096
|
const skills = {
|
|
1003
1097
|
claude: installAll || checked.includes(1),
|
|
1004
1098
|
codex: installAll || checked.includes(2)
|
|
1005
1099
|
};
|
|
1006
|
-
|
|
1100
|
+
const skillsSummary = installAll ? "\uBAA8\uB450 \uC124\uCE58 (Claude Code + Codex)" : [skills.claude && "Claude Code", skills.codex && "Codex"].filter(Boolean).join(", ") || "(\uC5C6\uC74C)";
|
|
1101
|
+
selectStep(flow, `\uC124\uCE58: ${skillsSummary}`);
|
|
1102
|
+
return { inputs: { project, mainLanguage, character, verify, skills }, session: flow };
|
|
1007
1103
|
} finally {
|
|
1008
1104
|
session.rl?.close();
|
|
1009
1105
|
}
|
|
@@ -1013,42 +1109,37 @@ async function handleExistingConfig(rl, projectRoot, c, now) {
|
|
|
1013
1109
|
const config = raw;
|
|
1014
1110
|
scaffoldGlobal();
|
|
1015
1111
|
const installedVer = installedEngineVersion();
|
|
1016
|
-
process.stdout.write("\n .awl/config.json \uC774 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4. \uD300\uC6D0\uC774 \uC124\uC815\uD574\uB450\uC5C8\uAD70\uC694.\n\n");
|
|
1017
|
-
process.stdout.write(` \uD504\uB85C\uC81D\uD2B8 ${config?.project ?? "(\uC5C6\uC74C)"}
|
|
1018
|
-
`);
|
|
1019
|
-
process.stdout.write(` \uC8FC \uC5B8\uC5B4 ${config?.mainLanguage?.join(", ") || "(\uC5C6\uC74C)"}
|
|
1020
|
-
`);
|
|
1021
|
-
process.stdout.write(` \uC131\uACA9 ${config?.character || "(\uC5C6\uC74C)"}
|
|
1022
|
-
`);
|
|
1023
1112
|
const engineNote = installedVer && config?.engineVersion ? installedVer === config.engineVersion ? `(\uC124\uCE58\uB428: ${installedVer} \uC77C\uCE58)` : `(\uC124\uCE58\uB428: ${installedVer} \uBD88\uC77C\uCE58 -> '\uADF8\uB300\uB85C \uC4F4\uB2E4'\uB97C \uACE0\uB974\uBA74 \uB3D9\uAE30\uD654\uB429\uB2C8\uB2E4)` : "";
|
|
1024
|
-
|
|
1025
|
-
|
|
1113
|
+
const summaryLines = [
|
|
1114
|
+
".awl/config.json \uC774 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4. \uD300\uC6D0\uC774 \uC124\uC815\uD574\uB450\uC5C8\uAD70\uC694.",
|
|
1115
|
+
"",
|
|
1116
|
+
`\uD504\uB85C\uC81D\uD2B8 ${config?.project ?? "(\uC5C6\uC74C)"}`,
|
|
1117
|
+
`\uC8FC \uC5B8\uC5B4 ${config?.mainLanguage?.join(", ") || "(\uC5C6\uC74C)"}`,
|
|
1118
|
+
`\uC131\uACA9 ${config?.character || "(\uC5C6\uC74C)"}`,
|
|
1119
|
+
`\uC5D4\uC9C4 ${config?.engineVersion ?? "(\uC5C6\uC74C)"} ${engineNote}`,
|
|
1120
|
+
...config?.verify ? ["", ...verifyLines(config.verify).map((l) => `\uAC80\uC99D ${l.trim()}`)] : [],
|
|
1121
|
+
"",
|
|
1122
|
+
"\uC774 \uC124\uC815\uC744 \uADF8\uB300\uB85C \uC4F0\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?"
|
|
1123
|
+
];
|
|
1124
|
+
const flow = openFlow("\uAE30\uC874 \uC124\uC815", c);
|
|
1125
|
+
process.stdout.write(`${flowConnector(c)}
|
|
1126
|
+
${flowActiveNode("\uAE30\uC874 \uC124\uC815", summaryLines, c)}
|
|
1026
1127
|
`);
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1128
|
+
const options = ["\uADF8\uB300\uB85C \uC4F4\uB2E4", "\uAC80\uC99D \uBA85\uB839\uC5B4\uB9CC \uACE0\uCE5C\uB2E4", "\uCC98\uC74C\uBD80\uD130 \uB2E4\uC2DC"];
|
|
1129
|
+
for (let i = 0; i < options.length; i++) {
|
|
1130
|
+
process.stdout.write(`${flowConnector(c)} ${i + 1}. ${options[i]}
|
|
1030
1131
|
`);
|
|
1031
|
-
}
|
|
1032
|
-
process.stdout.write("\n");
|
|
1033
1132
|
}
|
|
1034
|
-
process.stdout.write(" \uC774 \uC124\uC815\uC744 \uADF8\uB300\uB85C \uC4F0\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?\n\n");
|
|
1035
|
-
const options = ["\uADF8\uB300\uB85C \uC4F4\uB2E4", "\uAC80\uC99D \uBA85\uB839\uC5B4\uB9CC \uACE0\uCE5C\uB2E4", "\uCC98\uC74C\uBD80\uD130 \uB2E4\uC2DC"];
|
|
1036
|
-
process.stdout.write(
|
|
1037
|
-
`${sectionBox(
|
|
1038
|
-
"\uAE30\uC874 \uC124\uC815",
|
|
1039
|
-
options.map((option, i) => `${i + 1}. ${option}`),
|
|
1040
|
-
c
|
|
1041
|
-
)}
|
|
1042
|
-
`
|
|
1043
|
-
);
|
|
1044
1133
|
const choice = await promptNumber(rl, 0, options.length);
|
|
1134
|
+
selectStep(flow, `\uC120\uD0DD: ${options[choice]}`);
|
|
1135
|
+
closeFlow(flow);
|
|
1045
1136
|
process.stdout.write(
|
|
1046
1137
|
`
|
|
1047
1138
|
${makeColors(c.color).dim("\uADDC\uCE59\uACFC \uAD50\uD6C8\uC740 \uACF5\uC720\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC800 \uC124\uC815\uB9CC \uD300\uC6D0\uACFC \uAC19\uACE0, \uC313\uC774\uB294 \uAC83\uC740 \uB2F9\uC2E0 \uAC83\uC785\uB2C8\uB2E4.")}
|
|
1048
1139
|
`
|
|
1049
1140
|
);
|
|
1050
1141
|
if (choice === 0) {
|
|
1051
|
-
const synced = syncExistingInstall(projectRoot, installedVer ?? "unknown");
|
|
1142
|
+
const synced = syncExistingInstall(projectRoot, installedVer ?? "unknown", now);
|
|
1052
1143
|
if (synced.configUpdated || synced.skills.length > 0) {
|
|
1053
1144
|
process.stdout.write(
|
|
1054
1145
|
`
|
|
@@ -1082,11 +1173,10 @@ async function handleExistingConfig(rl, projectRoot, c, now) {
|
|
|
1082
1173
|
return;
|
|
1083
1174
|
}
|
|
1084
1175
|
rl.close();
|
|
1085
|
-
const inputs = await interactiveInputs(projectRoot, isGlobalInstalled(), c);
|
|
1176
|
+
const { inputs, session } = await interactiveInputs(projectRoot, isGlobalInstalled(), c);
|
|
1086
1177
|
const result = applyInit(projectRoot, inputs, now);
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
`);
|
|
1178
|
+
commitResultFlow(session, result, inputs, c);
|
|
1179
|
+
closeFlow(session);
|
|
1090
1180
|
}
|
|
1091
1181
|
function resolveProjectChoice(idx, candidates) {
|
|
1092
1182
|
if (idx >= 0 && idx < candidates.length) {
|
|
@@ -1157,13 +1247,14 @@ async function pickProjectRoot(cwd, c) {
|
|
|
1157
1247
|
}
|
|
1158
1248
|
return session.rl;
|
|
1159
1249
|
};
|
|
1250
|
+
const flow = openFlow("\uD504\uB85C\uC81D\uD2B8 \uC120\uD0DD", c);
|
|
1160
1251
|
const select = async (options, title) => {
|
|
1161
1252
|
if (raw) {
|
|
1162
1253
|
if (session.rl) {
|
|
1163
1254
|
session.rl.close();
|
|
1164
1255
|
session.rl = null;
|
|
1165
1256
|
}
|
|
1166
|
-
const r = await
|
|
1257
|
+
const r = await activeSelect(flow, options, 0, false, [], {
|
|
1167
1258
|
title,
|
|
1168
1259
|
hint: "\u2191\u2193 \uB610\uB294 j/k \uC774\uB3D9 \xB7 Enter \uC120\uD0DD \xB7 Esc \uAE30\uBCF8\uAC12 \uC720\uC9C0"
|
|
1169
1260
|
});
|
|
@@ -1178,6 +1269,7 @@ async function pickProjectRoot(cwd, c) {
|
|
|
1178
1269
|
"\uC5B4\uB290 \uD504\uB85C\uC81D\uD2B8\uC5D0 awl \uC744 \uBD99\uC77C\uAE4C\uC694?"
|
|
1179
1270
|
);
|
|
1180
1271
|
if (idx === 0) {
|
|
1272
|
+
selectStep(flow, `\uD504\uB85C\uC81D\uD2B8: ${cwd}`);
|
|
1181
1273
|
return cwd;
|
|
1182
1274
|
}
|
|
1183
1275
|
if (idx !== 1) {
|
|
@@ -1189,12 +1281,13 @@ async function pickProjectRoot(cwd, c) {
|
|
|
1189
1281
|
const title = candidates.length > 0 ? "\uD504\uB85C\uC81D\uD2B8\uB97C \uACE0\uB974\uC138\uC694 (\uCD5C\uADFC \uC218\uC815\uC21C, \uCD5C\uB300 20)\n" : "\uD558\uC704\uC5D0 git \uD504\uB85C\uC81D\uD2B8\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uC9C1\uC811 \uC785\uB825\uD558\uAC70\uB098 \uCDE8\uC18C\n";
|
|
1190
1282
|
const choice = resolveProjectChoice(await select(labels, title), candidates);
|
|
1191
1283
|
if (choice.kind === "path") {
|
|
1284
|
+
selectStep(flow, `\uD504\uB85C\uC81D\uD2B8: ${choice.path}`);
|
|
1192
1285
|
return choice.path;
|
|
1193
1286
|
}
|
|
1194
1287
|
if (choice.kind === "cancel") {
|
|
1195
1288
|
return null;
|
|
1196
1289
|
}
|
|
1197
|
-
const typed = (await ask(prompt(),
|
|
1290
|
+
const typed = (await ask(prompt(), `${flowConnector(c)} \uD504\uB85C\uC81D\uD2B8 \uACBD\uB85C\uB97C \uC785\uB825\uD558\uC138\uC694: `)).trim();
|
|
1198
1291
|
if (!typed) {
|
|
1199
1292
|
return null;
|
|
1200
1293
|
}
|
|
@@ -1205,11 +1298,13 @@ async function pickProjectRoot(cwd, c) {
|
|
|
1205
1298
|
`);
|
|
1206
1299
|
return null;
|
|
1207
1300
|
}
|
|
1301
|
+
selectStep(flow, `\uD504\uB85C\uC81D\uD2B8: ${resolved}`);
|
|
1208
1302
|
return resolved;
|
|
1209
1303
|
} finally {
|
|
1210
1304
|
if (session.rl) {
|
|
1211
1305
|
session.rl.close();
|
|
1212
1306
|
}
|
|
1307
|
+
closeFlow(flow);
|
|
1213
1308
|
}
|
|
1214
1309
|
}
|
|
1215
1310
|
async function runInit(opts) {
|
|
@@ -1226,7 +1321,7 @@ async function runInit(opts) {
|
|
|
1226
1321
|
if (configExists) {
|
|
1227
1322
|
const engine = scaffoldGlobal();
|
|
1228
1323
|
const hook = installSafetyHook(projectRoot);
|
|
1229
|
-
const synced = syncExistingInstall(projectRoot, engine.engineVersion);
|
|
1324
|
+
const synced = syncExistingInstall(projectRoot, engine.engineVersion, now);
|
|
1230
1325
|
const syncNote = synced.configUpdated || synced.skills.length > 0 ? `
|
|
1231
1326
|
${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(", ")})` : ""}.` : "";
|
|
1232
1327
|
process.stdout.write(
|
|
@@ -1268,14 +1363,16 @@ async function runInit(opts) {
|
|
|
1268
1363
|
}
|
|
1269
1364
|
return;
|
|
1270
1365
|
}
|
|
1271
|
-
const inputs = await interactiveInputs(chosenRoot, isGlobalInstalled(), c);
|
|
1366
|
+
const { inputs, session } = await interactiveInputs(chosenRoot, isGlobalInstalled(), c);
|
|
1272
1367
|
const result = applyInit(chosenRoot, inputs, now);
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
`);
|
|
1368
|
+
commitResultFlow(session, result, inputs, c);
|
|
1369
|
+
closeFlow(session);
|
|
1276
1370
|
}
|
|
1277
1371
|
|
|
1278
1372
|
export {
|
|
1373
|
+
openFlow,
|
|
1374
|
+
step,
|
|
1375
|
+
closeFlow,
|
|
1279
1376
|
scanGitProjects,
|
|
1280
1377
|
detectLanguage,
|
|
1281
1378
|
detectLanguages,
|
|
@@ -1303,9 +1400,14 @@ export {
|
|
|
1303
1400
|
verifyStepLines,
|
|
1304
1401
|
renderNonTtyNotice,
|
|
1305
1402
|
renderResult,
|
|
1403
|
+
commitResultFlow,
|
|
1306
1404
|
LANG_OPTIONS,
|
|
1307
1405
|
LANG_VALUES,
|
|
1308
1406
|
buildScreens,
|
|
1407
|
+
welcomeLines,
|
|
1408
|
+
langScreenLines,
|
|
1409
|
+
characterScreenLines,
|
|
1410
|
+
skillsScreenLines,
|
|
1309
1411
|
ask,
|
|
1310
1412
|
promptNumber,
|
|
1311
1413
|
selectSingle,
|