axmap-cli 0.0.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.
- package/.claude/commands/ax-done.md +10 -0
- package/.claude/commands/ax-setup.md +31 -0
- package/.claude/commands/ax-start.md +15 -0
- package/.claude/commands/ax-tell.md +14 -0
- package/.claude/commands/ax-update.md +19 -0
- package/.claude/commands/ax.md +13 -0
- package/CLAUDE.md +309 -0
- package/LICENSE +20 -0
- package/README.md +207 -0
- package/app/README.md +366 -0
- package/app/eval/edges.mjs +242 -0
- package/app/lib/adjacent.mjs +125 -0
- package/app/lib/agentcli.mjs +153 -0
- package/app/lib/analyze.mjs +1159 -0
- package/app/lib/cochange.mjs +421 -0
- package/app/lib/datanodes.mjs +127 -0
- package/app/lib/entry.mjs +192 -0
- package/app/lib/featuregraph.mjs +389 -0
- package/app/lib/features.mjs +645 -0
- package/app/lib/fetchrepo-run.mjs +37 -0
- package/app/lib/fetchrepo.mjs +164 -0
- package/app/lib/flow.mjs +1089 -0
- package/app/lib/ladder.mjs +387 -0
- package/app/lib/langs.mjs +630 -0
- package/app/lib/live.mjs +346 -0
- package/app/lib/llm.mjs +594 -0
- package/app/lib/newfile.mjs +126 -0
- package/app/lib/prdiff.mjs +651 -0
- package/app/lib/reveal.mjs +316 -0
- package/app/lib/roots.mjs +186 -0
- package/app/lib/scope.mjs +342 -0
- package/app/lib/session.mjs +389 -0
- package/app/lib/slots.mjs +233 -0
- package/app/lib/ssot.mjs +277 -0
- package/app/lib/teamview.mjs +962 -0
- package/app/lib/terms.ko.mjs +169 -0
- package/app/server.mjs +1959 -0
- package/app/web/shell.css +538 -0
- package/app/web/shell.html +197 -0
- package/app/web/shell.js +638 -0
- package/app/web/stage.js +347 -0
- package/app/web/words.js +85 -0
- package/bin/axmap.mjs +1918 -0
- package/governance/GOVERNANCE.md +433 -0
- package/governance/gate.mjs +526 -0
- package/governance/vote.mjs +501 -0
- package/mcp/README.md +254 -0
- package/mcp/SETUP-FOR-AI.md +186 -0
- package/mcp/install.ps1 +341 -0
- package/mcp/install.sh +339 -0
- package/mcp/server.mjs +969 -0
- package/package.json +48 -0
- package/src/closure.mjs +343 -0
- package/src/governance.mjs +839 -0
- package/src/invariants.mjs +226 -0
- package/src/mrtarget.mjs +284 -0
- package/src/promote.mjs +177 -0
- package/src/protocol.mjs +423 -0
- package/src/repotarget.mjs +81 -0
- package/src/update.mjs +177 -0
- package/src/version.mjs +186 -0
- package/tools/bus.mjs +520 -0
- package/tools/cluster-experiment.mjs +256 -0
- package/tools/cluster-sweep.mjs +226 -0
- package/tools/make-icon.mjs +108 -0
- package/tools/mcp-register.mjs +269 -0
- package/tools/mr-target.mjs +49 -0
- package/tools/persona-bench.mjs +362 -0
- package/tools/pick-repo.mjs +229 -0
- package/tools/promote.mjs +550 -0
- package/tools/reveal-demo.mjs +158 -0
- package/tools/run-tests.mjs +42 -0
- package/tools/setup.mjs +490 -0
- package/tools/shortcut.mjs +121 -0
- package/tools/smoke.mjs +166 -0
- package/tools/topicgraph.py +154 -0
- package/tools/vendor.mjs +382 -0
- package/tools/version.mjs +115 -0
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"//name": "๐ด npm ์ 'axmap' ์ 2022๋
๋ถํฐ ๋จ์ด ์ฐ๊ณ ์๋ ๋ค๋ฅธ ๊พธ๋ฌ๋ฏธ๋ค(leozin_ ์ Map ๋ผ์ด๋ธ๋ฌ๋ฆฌ, 1.1.2). ๊ทธ๋์ `npx axmap` ์ ์ฐ๋ฆฌ ๊ฒ์ด ์๋๊ณ , ๋๊ตฌ์๊ฒ๋ ๊ทธ๋ ๊ฒ ์๋ดํ๋ฉด ์ ๋๋ค. 2026-08-28 ์ axmap-cli ๋ก ์ ํ๋ค โ ์ค์ฝํ(@์ฌ์ฉ์/์ด๋ฆ)๋ฅผ ์ฐ์ง ์๋ ์ด์ ๋ ์ค์ฝํ๊ฐ npm ๊ณ์ ์ด๋ฆ์ ๋ฌถ์ฌ์ ๋์ค์ ํ์ด๋ ์กฐ์ง์ผ๋ก ์ฎ๊ธธ ๋ ์ด๋ฆ์ด ํต์งธ๋ก ๋ฐ๋๊ธฐ ๋๋ฌธ์ด๋ค. ์ฌ๋์ด ์น๋ **๋ช
๋ น** ์ด๋ฆ์ ๊ทธ๋๋ก axmap ์ด๋ค (์๋ bin) โ ๊พธ๋ฌ๋ฏธ ์ด๋ฆ๊ณผ ๋ช
๋ น ์ด๋ฆ์ ๋ฌ๋ผ๋ ๋๋ค.",
|
|
3
|
+
"name": "axmap-cli",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"//private": "๐ด ์ฌ๊ธฐ ์๋ \"private\": true ๋ฅผ 2026-08-28 ์ ์ง์ ๋ค. ๊ทธ ์ค์ด ์๋ ๋์ npm publish ๋ ๊ฑฐ๋ถ๋๋ค. ๋๋๋ฆฌ๋ ค๋ฉด ๋ค์ ๋ฃ์ผ๋ฉด ๋์ง๋ง, ์ด๋ฏธ ์ฌ๋ผ๊ฐ ๋ฒ์ ์ ๊ทธ๋๋ ์ ์ฌ๋ผ์ง๋ค โ npm ์ ๊ฐ์ ๋ฒํธ๋ฅผ ๋ฎ์ด์ฐ์ง ๋ชปํ๊ณ ์ญ์ ๋ 72์๊ฐ ์์๋ง ๋๋ค. ์ฆ ์ด ์ค์ ๋์ด๋ฆฌ๋ ๊ฒ์ '์์ผ๋ก ์ ์ฌ๋ฆฐ๋ค' ๋ ๋ป์ด์ง '์ฌ๋ฆฐ ๊ฒ์ ์์ค๋ค' ๋ ๋ป์ด ์๋๋ค.",
|
|
6
|
+
"//publishConfig": "axmap-cli ๋ ์ค์ฝํ๊ฐ ์์ด์ ๊ธฐ๋ณธ์ด ์ด๋ฏธ ๊ณต๊ฐ๋ค. ์ฆ ์ง๊ธ์ ์์ด๋ ๋๋ค. ๊ทธ๋๋ ๋จ๊ฒจ ๋๋ ์ด์ : ๋์ค์ @์กฐ์ง/axmap ์ฒ๋ผ ์ค์ฝํ๋ฅผ ๋ถ์ด๋ ๋ ์ด ์ค์ด ์์ผ๋ฉด publish ๊ฐ '์ ๋ฃ ํ๋์ด ํ์ํ๋ค'๋ ์๋ฑํ ๋ง๋ก ์คํจํ๋ค.",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"description": "axMap โ AI Experience ์ ์ง๋์ด์ ๊ฐ๋ฐ ํ๊ฒฝ์ AI Transformation. AI ์์ด์ ํธ๋ค์ด ์๋ก์ ์์
์์ญ์ ์นจ๋ฒํ์ง ์๋๋ก, ์ฝ๋ ์ถฉ๋ ๋์ ์๋ ์ถฉ๋์ ๋จผ์ ํฐ๋จ๋ฆฌ๋ git ์์ ์ ์ ํ๋กํ ์ฝ",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://lab.ssafy.com/rleaderjoon/axmap.git"
|
|
16
|
+
},
|
|
17
|
+
"keywords": ["ai-agent", "claim", "lock", "git", "mcp", "collaboration", "preemption"],
|
|
18
|
+
"bin": {
|
|
19
|
+
"axmap": "bin/axmap.mjs"
|
|
20
|
+
},
|
|
21
|
+
"//files": "npm ๊พธ๋ฌ๋ฏธ์ ๋ค์ด๊ฐ ๊ฒ. ์ด ๋ชฉ๋ก์ด ์์ผ๋ฉด ๋ฒค์น ์ฐ์ถ๋ฌผยท๋ฐ๋ชจยทํ
์คํธ๊น์ง ์ค๋ ค ๊พธ๋ฌ๋ฏธ๊ฐ ์์ญ MB ๊ฐ ๋๋ค. ์ฌ๊ธฐ์ ๋นผ๋ ๊ฒ๋ค(testยทdemoยทcorpusยทdesktopยทdocs)์ ์ค์นํ ์ฌ๋์๊ฒ ํ์ ์๋ค โ ๊ทธ๊ฑด ์ด ์ ์ฅ์๋ฅผ clone ํ ์ฌ๋์ ๊ฒ์ด๋ค.",
|
|
22
|
+
"files": [
|
|
23
|
+
"bin/",
|
|
24
|
+
"src/",
|
|
25
|
+
"mcp/",
|
|
26
|
+
"tools/",
|
|
27
|
+
"app/",
|
|
28
|
+
"governance/",
|
|
29
|
+
".claude/",
|
|
30
|
+
"CLAUDE.md"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"test": "node tools/run-tests.mjs",
|
|
34
|
+
"setup": "node tools/setup.mjs",
|
|
35
|
+
"demo": "bash demo/run-demo.sh",
|
|
36
|
+
"demo:compare": "bash demo/conflict-vs-parser.sh",
|
|
37
|
+
"demo:chaos": "bash demo/chaos.sh",
|
|
38
|
+
"app": "node app/server.mjs",
|
|
39
|
+
"smoke": "node tools/smoke.mjs",
|
|
40
|
+
"desktop": "npm --prefix desktop start",
|
|
41
|
+
"desktop:smoke": "npm --prefix desktop run selftest",
|
|
42
|
+
"dist": "npm --prefix desktop run dist",
|
|
43
|
+
"shortcut": "node tools/shortcut.mjs --dev"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20"
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/closure.mjs
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **import ํํฌ**(closure โ ์ง์
์ ์์ import ๋ฅผ ๋ฐ๋ผ ๋๊น์ง ๊ฐ์ ๋ ๋ฟ๋ ํ์ผ ์ ๋ถ)๋ฅผ
|
|
3
|
+
* ๊ตฌํ๋ ์์ ๊ณ์ฐ.
|
|
4
|
+
*
|
|
5
|
+
* ํ๋๋ผ๋ ๋น ์ง๋ฉด ์คํ์ด ์ ๋๊ณ , ํ๋๋ผ๋ ๋จ์ผ๋ฉด ์ ์ฐ๋ ํ์ผ์ ๋จ์ ์ ์ฅ์์
|
|
6
|
+
* ๋ณต์ฌํ๊ฒ ๋๋ค. ๊ทธ๋์ **๋ชฉ๋ก์ ์์ผ๋ก ์ ์ง ์๊ณ ์ฝ๋์์ ๊ตฌํ๋ค.**
|
|
7
|
+
*
|
|
8
|
+
* โโ ์ ์ด ํ์ผ์ด ๋ฐ๋ก ์๋๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
9
|
+
*
|
|
10
|
+
* ์ด ๋ชฉ๋ก์ ์ฐ๋ ๊ณณ์ด ๋์ด๋ค.
|
|
11
|
+
*
|
|
12
|
+
* `tools/vendor.mjs` ๋ฒค๋๋ง(vendoring โ ๋จ์ ์ฝ๋๋ฅผ ๋ด ์ ์ฅ์ ์์ ๋ณต์ฌํด
|
|
13
|
+
* ๋๊ณ ๊ทธ ์ฌ๋ณธ์ผ๋ก ๋๋ฆฌ๋ ๊ฒ) ํ ํ์ผ์ ๊ณ ๋ฅธ๋ค
|
|
14
|
+
* `test/closure.test.mjs` ๊ทธ ๋ชฉ๋ก์ด ๋๊ฑฐ๋ ์ค์ง ์์๋์ง ๋ณธ๋ค
|
|
15
|
+
*
|
|
16
|
+
* ๐ด ๋ ๋ฒ๋ก ์ ์ผ๋ฉด **์ด๊ธ๋ ์๊ฐ ํ
์คํธ๊ฐ ํต๊ณผํ๋ฉด์ ์ฌ๋ณธ์ด ๊นจ์ง๋ค.** ํ
์คํธ๊ฐ
|
|
17
|
+
* ์๊ธฐ ๋ชฉ๋ก์ ๋ณด๊ณ ์ด๋ก์ ๋ด๋๋ฐ ๋ฒค๋๋ฌ๋ ๋ค๋ฅธ ๋ชฉ๋ก์ ๋ณต์ฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
|
|
18
|
+
* ํ ํจ์๋ฅผ ๋์ด ๊ฐ์ ธ๋ค ์ด๋ค. `src/version.mjs` ๋ฅผ `tools/version.mjs` ์
|
|
19
|
+
* `src/mrtarget.mjs` ๊ฐ ํจ๊ป ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ์ด์ ๋ค.
|
|
20
|
+
*
|
|
21
|
+
* ๐ด ์ฌ๊ธฐ์๋ ํ์ผ์์คํ
์ด ์๋ค. ์ฝ๊ธฐ๋ `readFile` ์ธ์๋ก ๋ฐ๋๋ค.
|
|
22
|
+
* `src/governance.mjs` ๊ฐ git ์ ์ธ์๋ก ๋ฐ์ง ์๋ ๊ฒ๊ณผ ๊ฐ์ ์ด์ โ
|
|
23
|
+
* ํ์ ์ ๊ฒ์ฆํ๋ ค๊ณ ์ง์ง ์ ์ฅ์๋ฅผ ๋ง๋ค ํ์๊ฐ ์์ด์ผ ํ๋ค.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* CI ๊ฐ ์ง์ ๋ถ๋ฅด๋ ํ์ผ๋ค. `.gitlab-ci.yml` ์ `script:` ์ ์ ํ ๊ฒ๊ณผ ์น๊ฒฉ ๋ด์ด
|
|
28
|
+
* ์์ ํ๋ก์ธ์ค๋ก ๋์ฐ๋ ๊ฒ์ ํฉ์น ์๋ฆฌ๋ค.
|
|
29
|
+
*
|
|
30
|
+
* ๐ด **์ด ๋ชฉ๋ก๋ง ์์ผ๋ก ์ ๋๋ค.** ๋๋จธ์ง๋ ์ฌ๊ธฐ์ import ๋ฅผ ๋ฐ๋ผ๊ฐ ๊ตฌํ๋ค.
|
|
31
|
+
* ์ง์
์ ์ ์ฝ๋๊ฐ ์ ์ ์๋ค โ ๋ฌด์์ CI ๊ฐ ๋ถ๋ฅด๊ธฐ๋ก ํ๋์ง๋ ์ฌ๋์ ๊ฒฐ์ ์ด๋ค.
|
|
32
|
+
*
|
|
33
|
+
* `governance/vote.mjs` ๋ ์ง๊ธ `.gitlab-ci.yml` ์ ์์ง๋ง ๋ฃ๋๋ค. ์ฌ๋์ด ํ๋ฅผ
|
|
34
|
+
* ์ค ๋ ๋ถ๋ฅด๋ ์๋ฆฌ์ด๊ณ , ์ฌ๋ณธ์ ์์ผ๋ฉด ํ ์ ์ฅ์๋ฅผ clone ํ ์ฌ๋์ ํฌํ๋ฅผ ํ ์
|
|
35
|
+
* ์๋ค โ ํ๋ฅผ ์ ์ฅ์ ์์ ๋ ์ด์ ๊ฐ ํต์งธ๋ก ์ฌ๋ผ์ง๋ค.
|
|
36
|
+
*
|
|
37
|
+
* โโ ๐ด `bin/axmap.mjs` ์ `mcp/server.mjs` ๊ฐ ์ฌ๊ธฐ ์๋ ์ด์ โโโโโโโโโโโโโโโโโ
|
|
38
|
+
*
|
|
39
|
+
* ์ด ๋์ CI ๊ฐ ์๋๋ผ **์ฌ๋๊ณผ ์์ด์ ํธ๊ฐ** ๋ถ๋ฅธ๋ค. ๊ทธ๋ฐ๋ฐ๋ ๋ฃ๋ ์ด์ ๋ ํ๋๋ค:
|
|
40
|
+
*
|
|
41
|
+
* **ํ ์ ์ฅ์๋ง clone ํ ์ฌ๋์๊ฒ๋ ์ ์ (claim)์ด ์์ด์ผ ํ๋ค.**
|
|
42
|
+
*
|
|
43
|
+
* ์์ผ๋ฉด ์ถฉ๋ ๋ฐฉ์ง๊ฐ "๊ฐ์ axMap ์ ๋ฐ๋ก ์ค์นํ๋๊ฐ" ์ ๋ฌ๋ฆฌ๊ฒ ๋๋ค. ์ ํ ์ฌ๋
|
|
44
|
+
* ํ๋๊ฐ ๊ทธ๋ ์ ๋ชจ๋ ๋ณดํธ๋ฅผ ๋ฌดํจ๋ก ๋ง๋ค๊ณ , ํ ๊ท์น์ด ํ ์ ์ฅ์ ๋ฐ์ ๋ฌด์ธ๊ฐ์
|
|
45
|
+
* ์ธ์ง๋ก ์กํ๋ค. ์ฅ๋ถ(`axmap/claims`)๋ ํ ์ ์ฅ์์ ์๋๋ฐ ๊ทธ๊ฒ์ ์ฝ๊ณ ์ธ ๋๊ตฌ๊ฐ
|
|
46
|
+
* ์๋ ์ํ๊ฐ ์ ์ผ ์ด์ํ๋ค โ ๋ฐ์ดํฐ๋ ์๊ณ ์ด์ ๊ฐ ์๋ ๊ฒ์ด๋ค.
|
|
47
|
+
*
|
|
48
|
+
* bin/axmap.mjs claim ยท release ยท status ยท verify(ํ
) ยท audit
|
|
49
|
+
* mcp/server.mjs AI ๋๊ตฌ๊ฐ ๋ถ๋ ์ฐฝ๊ตฌ. clone ๋ง์ผ๋ก `ax_claim` ์ด ๋ฌ๋ค
|
|
50
|
+
* tools/bus.mjs ์์ด์ ํธ๋ผ๋ฆฌ ์ชฝ์ง (`ax_inbox` ยท `ax_send`)
|
|
51
|
+
*
|
|
52
|
+
* ๐ด `tools/bus.mjs` ๋ฅผ ๋์ณค๋ค๊ฐ ์ค์ ๋ก ๊นจ๋จ๋ ธ๋ค. ์ด ํํฌ๋ **`import` ๋ง ๋ฐ๋ผ๊ฐ๋ค.**
|
|
53
|
+
* ๊ทธ๋ฐ๋ฐ `mcp/server.mjs` ๋ bus ๋ฅผ import ํ์ง ์๊ณ **์์ ํ๋ก์ธ์ค๋ก ๋์ด๋ค**
|
|
54
|
+
* (`path.join(SELF, 'tools', 'bus.mjs')`). ๊ทธ๋์ ์ฌ๋ณธ์ ์ ๋ค์ด๊ฐ๊ณ ,
|
|
55
|
+
* `ax_inbox` ๋ฅผ ๋ถ๋ฅด๋ฉด "Cannot find module" ๋ก ์ฃฝ์๋ค.
|
|
56
|
+
*
|
|
57
|
+
* ๊ตํ: **spawn ๋๋ ํ์ผ์ import ๊ทธ๋ํ์ ์ ์กํ๋ค.** ์ง์
์ ๋ชฉ๋ก์ ์์ผ๋ก
|
|
58
|
+
* ์ ๋ ์ด์ ๊ฐ ์ ํํ ์ด๊ฒ์ด๋ค โ ๋ฌด์์ด ์คํ๋๋์ง๋ ์ฝ๋๊ฐ ์ ์ ์๋ค.
|
|
59
|
+
* ์ ํ์ผ์ spawn ํ๊ฒ ๋๋ฉด ์ฌ๊ธฐ์๋ ๋ํด์ผ ํ๋ค.
|
|
60
|
+
*
|
|
61
|
+
* ์ ์ญ ์ค์น(`~/.axmap/app`)๋ฅผ ๋์ ํ๋ ๊ฒ์ด ์๋๋ค. ๋์ ๊ฐ์ด ์ฐ๋ค โ ํ ์ ์ฅ์
|
|
62
|
+
* ์์์๋ `.mcp.json` ์ด ์ด ์ฌ๋ณธ์ ๊ฐ๋ฆฌํค๊ณ , ๋ค๋ฅธ ์ ์ฅ์์์๋ ์ ์ญ์ด ๋ฐ๋๋ค.
|
|
63
|
+
*
|
|
64
|
+
* ๋๊ฐ๋ ์ ์งํ๊ฒ ์ ์ด ๋๋ค: **`bin/axmap.mjs` ๋ ์ด ์ ์ฅ์์์ ์ ์ผ ์์ฃผ ๋ฐ๋๋
|
|
65
|
+
* ํ์ผ์ด๋ผ, ์ฌ๋ณธ์ ๋ค์ ๋ง๋ค ์ผ์ด ๊ทธ๋งํผ ์์ฃผ ์๊ธด๋ค.** ๊ทธ ๋น์ฉ์ ๋ด๊ณ ์ฌ๋ ๊ฒ์ด
|
|
66
|
+
* "์ค์น ์ ํ ์ฌ๋ ๋๋ฌธ์ ๋ณดํธ๊ฐ ์ฌ๋ผ์ง๋ ๊ฒ" ๋ณด๋ค ๋ซ๋ค๊ณ ํ๋จํ๋ค.
|
|
67
|
+
*/
|
|
68
|
+
export const CI_ENTRYPOINTS = Object.freeze([
|
|
69
|
+
'governance/gate.mjs',
|
|
70
|
+
'governance/vote.mjs',
|
|
71
|
+
'tools/mr-target.mjs',
|
|
72
|
+
'tools/promote.mjs',
|
|
73
|
+
'tools/version.mjs',
|
|
74
|
+
'bin/axmap.mjs',
|
|
75
|
+
'mcp/server.mjs',
|
|
76
|
+
'tools/bus.mjs',
|
|
77
|
+
])
|
|
78
|
+
|
|
79
|
+
/** ์ฌ๋์ ํ๋๊ฐ `/` ๋ก ์์ํ๋ฉด ๋๋์
์ด ์๋๋ผ ์ ๊ท์์ด ์ฌ ์ ์๋ ์๋ฆฌ๋ค. */
|
|
80
|
+
const REGEX_MAY_FOLLOW = new Set(
|
|
81
|
+
['', '(', ',', '=', ':', '[', '!', '&', '|', '?', '{', '}', ';', '+', '-', '*', '%', '<', '>', '~', '^', '\n'],
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
/** ๊ฐ์ ํ๋จ์ ๋ฑ๊ธ์๊ฐ ์๋๋ผ ๋ฑ๋ง๋ก ํด์ผ ํ๋ ๊ฒฝ์ฐ (`return /re/` ์ฒ๋ผ). */
|
|
85
|
+
const REGEX_MAY_FOLLOW_WORD = new Set(
|
|
86
|
+
['return', 'typeof', 'case', 'in', 'of', 'delete', 'void', 'instanceof', 'new', 'do', 'else', 'yield', 'await'],
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
const isWordChar = (c) => /[A-Za-z0-9_$]/.test(c)
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* ์ฃผ์์ ์ง์ด๋ค. ๋ฌธ์์ดยทํ
ํ๋ฆฟยท์ ๊ท์ ๋ฆฌํฐ๋ด **์**์ ๊ฑด๋๋ฆฌ์ง ์๋๋ค.
|
|
93
|
+
*
|
|
94
|
+
* โโ ์ ์ง์ฐ๊ณ ์์ํ๋๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
95
|
+
*
|
|
96
|
+
* ์ด ์ ์ฅ์์ ํ์ผ๋ค์ ๋จธ๋ฆฌ๋ง ์ฃผ์์ ์ฌ์ฉ๋ฒ์ ์ ์ด ๋๋ค. ๊ฑฐ๊ธฐ์
|
|
97
|
+
* `node axmap/governance/gate.mjs` ๊ฐ์ ์ค์ด ๊ทธ๋๋ก ์๊ณ , `import` ๋ผ๋ ๋ฑ๋ง๋
|
|
98
|
+
* ์ค๋ช
๋ฌธ์ ๋์จ๋ค. ์ฃผ์์ ๋จ๊ฒจ ๋๊ณ ์ ๊ท์์ ๋๋ฆฌ๋ฉด **์ฃผ์์ ์ ํ ์์๋ฅผ ์ง์ง
|
|
99
|
+
* import ๋ก ์ธ์ด** ์์ง๋ ์์ ํ์ผ์ ๋ณต์ฌ ๋ชฉ๋ก์ ๋ฃ๊ฒ ๋๋ค.
|
|
100
|
+
*
|
|
101
|
+
* ๐ด ๋ฐ๋๋ก ๋ฌธ์์ด์ ์ง์ฐ๋ฉด ์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ฐพ๋ ๊ฒ์ด ๋ฐ๋ก ๋ฌธ์์ด์ด๋ค.
|
|
102
|
+
* ๊ทธ๋์ "์ฃผ์๋ง" ์ง์ด๋ค. ์ ๊ท์ ๋ฆฌํฐ๋ด์ ๋ฐ๋ก ์์๋ณด๋ ์ด์ ๋ ํ๋๋ฟ์ด๋ค โ
|
|
103
|
+
* `/[a-z]\/\//` ๊ฐ์ ๊ฒ์ ์ฃผ์ ์์์ผ๋ก ์๋ชป ์ฝ์ผ๋ฉด ๊ทธ ๋ค๊ฐ ํต์งธ๋ก ์ฌ๋ผ์ง๋ค.
|
|
104
|
+
*/
|
|
105
|
+
export function stripComments(source) {
|
|
106
|
+
const src = String(source ?? '')
|
|
107
|
+
let out = ''
|
|
108
|
+
let i = 0
|
|
109
|
+
let prev = '' // ์ง์ ์ ๊ณต๋ฐฑ ์๋ ์ฝ๋ ๊ธ์
|
|
110
|
+
let word = '' // ๊ทธ ๊ธ์๋ก ๋๋๋ ๋ฑ๋ง (์์ผ๋ฉด ๋น ๋ฌธ์์ด)
|
|
111
|
+
|
|
112
|
+
const regexMayFollow = () => REGEX_MAY_FOLLOW.has(prev) || REGEX_MAY_FOLLOW_WORD.has(word)
|
|
113
|
+
const advance = (c) => {
|
|
114
|
+
if (/\s/.test(c)) return // ๊ณต๋ฐฑ์ ๋ฑ๋ง์ ๋์ง ์๋๋ค. `return /re/` ์ ์์๋ณด๋ ค๋ฉด ํ์ํ๋ค
|
|
115
|
+
if (isWordChar(c)) word += c
|
|
116
|
+
else word = ''
|
|
117
|
+
prev = c
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
while (i < src.length) {
|
|
121
|
+
const c = src[i]
|
|
122
|
+
const d = src[i + 1]
|
|
123
|
+
|
|
124
|
+
if (c === '/' && d === '/') {
|
|
125
|
+
while (i < src.length && src[i] !== '\n') i++
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (c === '/' && d === '*') {
|
|
130
|
+
i += 2
|
|
131
|
+
while (i < src.length && !(src[i] === '*' && src[i + 1] === '/')) i++
|
|
132
|
+
i += 2
|
|
133
|
+
out += ' ' // ์ฃผ์์ด ๋ถ์ด ์๋ ๋ ํ ํฐ์ด ํ ๋ฑ๋ง๋ก ๋ถ์ง ์๊ฒ ์๋ฆฌ๋ฅผ ๋จ๊ธด๋ค
|
|
134
|
+
prev = ''
|
|
135
|
+
word = ''
|
|
136
|
+
continue
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
140
|
+
out += c
|
|
141
|
+
i++
|
|
142
|
+
while (i < src.length) {
|
|
143
|
+
if (src[i] === '\\') {
|
|
144
|
+
out += src[i] + (src[i + 1] ?? '')
|
|
145
|
+
i += 2
|
|
146
|
+
continue
|
|
147
|
+
}
|
|
148
|
+
const ch = src[i]
|
|
149
|
+
out += ch
|
|
150
|
+
i++
|
|
151
|
+
if (ch === c) break
|
|
152
|
+
}
|
|
153
|
+
prev = c
|
|
154
|
+
word = ''
|
|
155
|
+
continue
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (c === '/' && regexMayFollow()) {
|
|
159
|
+
out += c
|
|
160
|
+
i++
|
|
161
|
+
let inClass = false
|
|
162
|
+
while (i < src.length) {
|
|
163
|
+
const ch = src[i]
|
|
164
|
+
if (ch === '\\') {
|
|
165
|
+
out += ch + (src[i + 1] ?? '')
|
|
166
|
+
i += 2
|
|
167
|
+
continue
|
|
168
|
+
}
|
|
169
|
+
if (ch === '\n') break // ์ค์ ๋๋ ์ ๊ท์ ๋ฆฌํฐ๋ด์ ์๋ค. ์๋ชป ์ง์๋ค๋ ๋ป์ด๋ ๋ฉ์ถ๋ค
|
|
170
|
+
out += ch
|
|
171
|
+
i++
|
|
172
|
+
if (ch === '[') inClass = true
|
|
173
|
+
else if (ch === ']') inClass = false
|
|
174
|
+
else if (ch === '/' && !inClass) break
|
|
175
|
+
}
|
|
176
|
+
prev = '/'
|
|
177
|
+
word = ''
|
|
178
|
+
continue
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
out += c
|
|
182
|
+
advance(c)
|
|
183
|
+
i++
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return out
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/*
|
|
190
|
+
* import ๋ฅผ ์์๋ณด๋ ์ธ ๊ฐ์ง ๋ชจ์.
|
|
191
|
+
*
|
|
192
|
+
* `[^'";()]*?` ๋ก ๊ฐ์ด๋ฐ๋ฅผ ๋ง์ ๋ ๊ฒ์ ํ ๋ฌธ์ฅ์ ๋์ด๊ฐ์ง ๋ชปํ๊ฒ ํ๊ธฐ ์ํด์๋ค.
|
|
193
|
+
* ์ด๊ฑธ `[\s\S]*?` ๋ก ๋๋ฉด ์ ์ค์ `import` ์ ํ์ฐธ ๋ค์ `from` ์ด ์ง์ง์ด์ ธ ์๋ฑํ
|
|
194
|
+
* ๋ฌธ์์ด์ ๊ฒฝ๋ก๋ก ์ฝ๋๋ค.
|
|
195
|
+
*
|
|
196
|
+
* ์๋ ค์ง ํ๊ณ: `export const from = './x.mjs'` ์ฒ๋ผ `from` ์ ๋ณ์ ์ด๋ฆ์ผ๋ก ์ฐ๋ฉด
|
|
197
|
+
* ๊ฑฐ์ง ์์ฑ์ด ๋๋ค. ๊ทธ๋๋ ๊ทธ ๊ฒฝ๋ก๊ฐ bare ๋ ์๋ ํ์ผ๋ก ์กํ ํ
์คํธ๊ฐ ๋นจ๊ฐ์ง๋ค โ
|
|
198
|
+
* ์กฐ์ฉํ ์ง๋๊ฐ์ง๋ ์๋๋ค.
|
|
199
|
+
*/
|
|
200
|
+
const RE_FROM = /(?:^|[\s;})])(?:import|export)\s[^'";()]*?\bfrom\s*(['"])([^'"]+)\1/gm
|
|
201
|
+
const RE_SIDE_EFFECT = /(?:^|[\s;})])import\s*(['"])([^'"]+)\1/gm
|
|
202
|
+
const RE_DYNAMIC = /\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/gm
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* ์์ค ํ ๋ฒ์์ import ๋์ ๋ฌธ์์ด์ ์ ๋ถ ๋ฝ๋๋ค. ์ฃผ์์ ๋จผ์ ์ง์ด๋ค.
|
|
206
|
+
*
|
|
207
|
+
* `import.meta.url` ์ ๊ฑธ๋ฆฌ์ง ์๋๋ค โ ์ธ ์ ๊ท์ ๋ชจ๋ `import` ๋ค์ ๊ณต๋ฐฑ์ด๋
|
|
208
|
+
* ์ฌ๋ ๊ดํธ๋ฅผ ์๊ตฌํ๊ณ , `.` ์ ์ด๋ ์ชฝ๋ ์๋๋ค.
|
|
209
|
+
*/
|
|
210
|
+
export function importSpecifiers(source) {
|
|
211
|
+
const code = stripComments(source)
|
|
212
|
+
const found = []
|
|
213
|
+
for (const re of [RE_FROM, RE_SIDE_EFFECT, RE_DYNAMIC]) {
|
|
214
|
+
re.lastIndex = 0
|
|
215
|
+
let m
|
|
216
|
+
while ((m = re.exec(code)) !== null) found.push(m[2])
|
|
217
|
+
}
|
|
218
|
+
return found
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* import ๋์์ ์
์ผ๋ก ๊ฐ๋ฅธ๋ค.
|
|
223
|
+
*
|
|
224
|
+
* `builtin` `node:fs` ์ฒ๋ผ Node ๊ฐ ๋ค๊ณ ์๋ ๊ฒ. ๋ณต์ฌํ ๊ฒ์ด ์๋ค
|
|
225
|
+
* `relative` `./x.mjs` ยท `../src/y.mjs`. ๋ฐ๋ผ๊ฐ์ ๊ฐ์ด ๋ณต์ฌํด์ผ ํ๋ค
|
|
226
|
+
* `bare` ๊ทธ ๋ฐ ์ ๋ถ. npm ํจํค์ง์ด๊ฑฐ๋ `fs` ์ฒ๋ผ `node:` ๋ฅผ ๋น ๋จ๋ฆฐ ๊ฒ
|
|
227
|
+
*
|
|
228
|
+
* ๐ด `fs` ๋ฅผ `bare` ๋ก ์ธ๋ ๊ฒ์ ์ค์๊ฐ ์๋๋ค. ์ ๋์ฌ ์๋ ๋ด์ฅ ์ด๋ฆ์ ๊ฐ์
|
|
229
|
+
* ์ด๋ฆ์ npm ํจํค์ง์ ๊ฐ๋ ค์ง ์ ์๊ณ , ๊ทธ๋ฌ๋ฉด ์ด๋ ์ชฝ์ด ๋ก๋๋๋์ง ์ฝ๋๋ง
|
|
230
|
+
* ๋ณด๊ณ ๋ ์ ์ ์๋ค. ์ด ์ ์ฅ์๋ `node:` ๋ฅผ ๋ถ์ด๊ธฐ๋ก ํ์ผ๋ฏ๋ก ์ ๋ถ์ ๊ฒ์
|
|
231
|
+
* ๊ตฌ๋ถ ์์ด ๋นจ๊ฐ๊ฒ ๋ง๋ ๋ค.
|
|
232
|
+
*/
|
|
233
|
+
export function classifySpecifier(spec) {
|
|
234
|
+
const s = String(spec ?? '')
|
|
235
|
+
if (s.startsWith('node:')) return 'builtin'
|
|
236
|
+
if (s === '.' || s === '..' || s.startsWith('./') || s.startsWith('../')) return 'relative'
|
|
237
|
+
return 'bare'
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** posix ๊ฒฝ๋ก ๊ณ์ฐ. `path` ๋ชจ๋์ ์ ์ฐ๋ ์ด์ ๋ Windows ์์ `\` ๊ฐ ์์ด๋ฉด ์ ๋์ด์๋ค. */
|
|
241
|
+
function posixDirname(rel) {
|
|
242
|
+
const i = rel.lastIndexOf('/')
|
|
243
|
+
return i < 0 ? '' : rel.slice(0, i)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* `fromRel` ์์ `spec` ์ด ๊ฐ๋ฆฌํค๋ ํ์ผ์ ๋ฃจํธ ๊ธฐ์ค ์๋ ๊ฒฝ๋ก๋ก ๋๋ ค์ค๋ค.
|
|
248
|
+
* ๋ฃจํธ ๋ฐ์ผ๋ก ๋๊ฐ๋ฉด `null` โ ๋ณต์ฌํ ์ ์๋ ๊ฒ์ด๋ฏ๋ก ๋ถ๋ฅด๋ ์ชฝ์ด ์์์ผ ํ๋ค.
|
|
249
|
+
*/
|
|
250
|
+
export function resolveImport(fromRel, spec) {
|
|
251
|
+
const parts = `${posixDirname(String(fromRel))}/${String(spec)}`.split('/')
|
|
252
|
+
const stack = []
|
|
253
|
+
for (const p of parts) {
|
|
254
|
+
if (p === '' || p === '.') continue
|
|
255
|
+
if (p === '..') {
|
|
256
|
+
if (stack.length === 0) return null // ๋ฃจํธ๋ฅผ ๋ซ๊ณ ์ฌ๋ผ๊ฐ๋ค
|
|
257
|
+
stack.pop()
|
|
258
|
+
continue
|
|
259
|
+
}
|
|
260
|
+
stack.push(p)
|
|
261
|
+
}
|
|
262
|
+
return stack.length === 0 ? null : stack.join('/')
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* ์ง์
์ ์์ ์ถ๋ฐํด ๋ฟ๋ ํ์ผ ์ ๋ถ๋ฅผ ๋ชจ์๋ค.
|
|
267
|
+
*
|
|
268
|
+
* @param {object} opts
|
|
269
|
+
* @param {string[]} [opts.entries] ๋ฃจํธ ๊ธฐ์ค ์๋ ๊ฒฝ๋ก. ๊ธฐ๋ณธ์ `CI_ENTRYPOINTS`
|
|
270
|
+
* @param {(rel: string) => (string|null)} opts.readFile
|
|
271
|
+
* ํ์ผ ๋ด์ฉ. ์์ผ๋ฉด `null` ์ ์ค๋ค (๋์ง์ง ์๋๋ค โ ์๋ ํ์ผ๋ ๊ฒฐ๊ณผ์ ์ผ๋ถ๋ค)
|
|
272
|
+
* @returns {{files: string[], bare: {file: string, spec: string}[],
|
|
273
|
+
* missing: string[], outside: {file: string, spec: string}[], entries: string[]}}
|
|
274
|
+
*
|
|
275
|
+
* ๐ด ๋ชป ์ฝ์ ํ์ผ์ ์์ธ๋ก ํฐ๋จ๋ฆฌ์ง ์๊ณ `missing` ์ ๋ด๋ ์ด์ : ๋ถ๋ฅด๋ ์ชฝ์ด
|
|
276
|
+
* "๋ฌด์์ด ์ ์ ๋๋์ง" ๋ฅผ ํ ๋ฒ์ ๋ณด๊ณ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฒซ ๋ฒ์งธ์์ ์ฃฝ์ผ๋ฉด
|
|
277
|
+
* ๋ ๋ฒ์งธ ๋ฌธ์ ๋ ๋ค์ ์คํ์์์ผ ๋ณด์ธ๋ค.
|
|
278
|
+
*/
|
|
279
|
+
export function importClosure({ entries = CI_ENTRYPOINTS, readFile } = {}) {
|
|
280
|
+
if (typeof readFile !== 'function') throw new TypeError('importClosure: readFile ํจ์๊ฐ ํ์ํฉ๋๋ค')
|
|
281
|
+
|
|
282
|
+
const entryList = [...entries]
|
|
283
|
+
const files = new Set()
|
|
284
|
+
const bare = []
|
|
285
|
+
const missing = []
|
|
286
|
+
const outside = []
|
|
287
|
+
const seen = new Set()
|
|
288
|
+
const queue = [...entryList]
|
|
289
|
+
|
|
290
|
+
while (queue.length > 0) {
|
|
291
|
+
const rel = queue.shift()
|
|
292
|
+
if (seen.has(rel)) continue
|
|
293
|
+
seen.add(rel)
|
|
294
|
+
|
|
295
|
+
const source = readFile(rel)
|
|
296
|
+
if (source == null) {
|
|
297
|
+
missing.push(rel)
|
|
298
|
+
continue
|
|
299
|
+
}
|
|
300
|
+
files.add(rel)
|
|
301
|
+
|
|
302
|
+
for (const spec of importSpecifiers(source)) {
|
|
303
|
+
const kind = classifySpecifier(spec)
|
|
304
|
+
if (kind === 'builtin') continue
|
|
305
|
+
if (kind === 'bare') {
|
|
306
|
+
bare.push({ file: rel, spec })
|
|
307
|
+
continue
|
|
308
|
+
}
|
|
309
|
+
const next = resolveImport(rel, spec)
|
|
310
|
+
if (next === null) {
|
|
311
|
+
outside.push({ file: rel, spec })
|
|
312
|
+
continue
|
|
313
|
+
}
|
|
314
|
+
queue.push(next)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return { files: [...files].sort(), bare, missing, outside, entries: entryList }
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* ํํฌ๋ฅผ ๊ตฌํ๋ค ๋ง๋ ๋ฌธ์ ๋ฅผ ์ฌ๋์ด ์ฝ๋ ์ค๋ก ๋ฐ๊พผ๋ค. ๋ฌธ์ ๊ฐ ์์ผ๋ฉด ๋น ๋ฐฐ์ด.
|
|
323
|
+
*
|
|
324
|
+
* ๋ฒค๋๋ฌ์ ํ
์คํธ๊ฐ ๊ฐ์ ๋ฌธ์ฅ์ ๋ด์ผ ํ๋ค โ ํ์ชฝ์์ ๋ณธ ๋ฉ์์ง๋ฅผ ๋ค๋ฅธ ์ชฝ์์
|
|
325
|
+
* ๊ฒ์ํ์ ๋ ์ ๋์ค๋ฉด ๊ฐ์ ๋ฌธ์ ์ธ์ง ์ ์ ์๋ค.
|
|
326
|
+
*/
|
|
327
|
+
export function formatClosureProblems(closure) {
|
|
328
|
+
const lines = []
|
|
329
|
+
for (const rel of closure.missing) {
|
|
330
|
+
lines.push(`์๋ ํ์ผ์ import ํฉ๋๋ค: ${rel}`)
|
|
331
|
+
}
|
|
332
|
+
for (const { file, spec } of closure.outside) {
|
|
333
|
+
lines.push(`๋ฃจํธ ๋ฐ์ import ํฉ๋๋ค: ${file} โ ${spec} (๋ณต์ฌํ ์ ์์ต๋๋ค)`)
|
|
334
|
+
}
|
|
335
|
+
for (const { file, spec } of closure.bare) {
|
|
336
|
+
lines.push(
|
|
337
|
+
`Node ๋ด์ฅ์ด ์๋ ๊ฒ์ import ํฉ๋๋ค: ${file} โ '${spec}'\n` +
|
|
338
|
+
` ๋ด์ฅ์ด๋ผ๋ฉด 'node:${spec}' ์ฒ๋ผ ์ ๋์ฌ๋ฅผ ๋ถ์ด์ธ์.\n` +
|
|
339
|
+
` ํจํค์ง๋ผ๋ฉด CI ์ง์
์ ์์ ๋ฟ๋ ์๋ฆฌ์ ๋ ์ ์์ต๋๋ค โ ์ฌ๋ณธ์๋ node_modules ๊ฐ ์์ต๋๋ค.`,
|
|
340
|
+
)
|
|
341
|
+
}
|
|
342
|
+
return lines
|
|
343
|
+
}
|