axmap-cli 1.0.0 → 1.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/bin/axmap.mjs +63 -1
- package/package.json +1 -1
- package/tools/bus.mjs +110 -3
- package/.claude/settings.local.json +0 -32
package/bin/axmap.mjs
CHANGED
|
@@ -1172,6 +1172,32 @@ function busSetupFailed(r) {
|
|
|
1172
1172
|
return 'failed'
|
|
1173
1173
|
}
|
|
1174
1174
|
|
|
1175
|
+
/**
|
|
1176
|
+
* 쪽지함만 준비한다. **장부는 건드리지 않는다.**
|
|
1177
|
+
*
|
|
1178
|
+
* 🔴 왜 `init` 을 부르지 않고 이 명령이 따로 있는가. 쪽지를 **읽는** 길에서
|
|
1179
|
+
* 부를 자리가 필요해서다. `init` 은 장부(`axmap/claims`)까지 만들고 그것을
|
|
1180
|
+
* 원격에 push 한다 — "내 쪽지 좀 보자" 가 남의 저장소에 **선점 장부**를
|
|
1181
|
+
* 만드는 일이 되면 안 된다. 쪽지 브랜치는 쪽지함이 원래 사는 곳이므로
|
|
1182
|
+
* 거기까지는 간다. 선을 긋는 자리는 "읽으려는 그것" 과 "그 밖의 것" 사이다.
|
|
1183
|
+
*
|
|
1184
|
+
* 그래서 `tools/bus.mjs` 는 쪽지함이 없을 때 이 명령을 부른다. 만드는 코드를
|
|
1185
|
+
* 저쪽에 복사하지 않는 이유는 사본이 곧 두 벌이고, 두 벌은 반드시 어긋나기
|
|
1186
|
+
* 때문이다 — 이 저장소가 팀 사본을 걷어낸 것과 같은 이유다.
|
|
1187
|
+
*/
|
|
1188
|
+
function cmdBusRepair() {
|
|
1189
|
+
const root = repoRoot()
|
|
1190
|
+
// .axmap 을 손으로 지웠어도 git 쪽에 worktree 등록이 남아 add 가 실패한다.
|
|
1191
|
+
git(['worktree', 'prune'], { cwd: root })
|
|
1192
|
+
const r = ensureBus(root)
|
|
1193
|
+
if (r === 'failed') process.exit(1)
|
|
1194
|
+
console.log(
|
|
1195
|
+
r === 'ready'
|
|
1196
|
+
? `쪽지함이 이미 있습니다: ${BUS_REL}`
|
|
1197
|
+
: `쪽지함을 만들었습니다: ${BUS_REL} (${BUS_BRANCH})`,
|
|
1198
|
+
)
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1175
1201
|
function cmdInit(flags = {}) {
|
|
1176
1202
|
const root = repoRoot()
|
|
1177
1203
|
const dir = ledgerDir(root)
|
|
@@ -1664,7 +1690,16 @@ function collectCodeCommits(root, range) {
|
|
|
1664
1690
|
for (const line of log.out ? log.out.split(NL) : []) {
|
|
1665
1691
|
if (!line) continue
|
|
1666
1692
|
const [sha, author, ct, subject] = line.split(NUL)
|
|
1667
|
-
|
|
1693
|
+
// 🔴 `-c core.quotepath=false` 가 없으면 **한글 경로가 claim 과 안 맞는다.**
|
|
1694
|
+
// git 은 기본으로 ASCII 밖 글자를 역슬래시 + 8진수 세 자리로 감싸 내보낸다.
|
|
1695
|
+
// 그 문자열은 장부에 적힌 경로와 절대 같아질 수 없고, 검사는 "안 겹친다" 로
|
|
1696
|
+
// **조용히 통과**한다 - 락에서 최악인 fail-open 이다.
|
|
1697
|
+
// 팀 CI 가 잡 안에서 `git config core.quotepath false` 로 막고 있었다.
|
|
1698
|
+
// 우회는 그 잡에만 걸린다. 부르는 자리에서 못을 박는다 (verify 와 같은 방식).
|
|
1699
|
+
const files = git(
|
|
1700
|
+
['-c', 'core.quotepath=false', 'show', '--no-renames', '--name-only', '--format=', sha],
|
|
1701
|
+
{ cwd: root },
|
|
1702
|
+
).out
|
|
1668
1703
|
out.push({
|
|
1669
1704
|
sha,
|
|
1670
1705
|
author,
|
|
@@ -2186,6 +2221,8 @@ const HELP = `axmap - AI 에이전트 작업 선점 프로토콜
|
|
|
2186
2221
|
axmap setup 이 PC 와 이 저장소에 axMap 을 붙인다 (첫 한 번)
|
|
2187
2222
|
[--remote <이름|git 주소>] [--name] [--dry-run]
|
|
2188
2223
|
axmap init 장부(고아 브랜치 + worktree)를 준비한다
|
|
2224
|
+
axmap bus-repair 쪽지함만 준비한다 (장부는 안 건드린다)
|
|
2225
|
+
쪽지를 읽다가 "쪽지함을 못 열었습니다" 를 봤을 때
|
|
2189
2226
|
axmap claim <경로...> 경로를 선점한다 [--task --intent --ttl 30m]
|
|
2190
2227
|
axmap release [경로...] 반납한다 (경로 생략 시 전부)
|
|
2191
2228
|
axmap renew TTL 을 연장한다 [--ttl 30m]
|
|
@@ -2197,6 +2234,7 @@ const HELP = `axmap - AI 에이전트 작업 선점 프로토콜
|
|
|
2197
2234
|
axmap doctor 이 PC 에서 선점이 실제로 도는지 점검 [--json]
|
|
2198
2235
|
axmap hook install verify 를 pre-commit 훅으로 설치
|
|
2199
2236
|
axmap update 새 버전이 있는지 묻는다 (바꾸지는 않는다)
|
|
2237
|
+
axmap --version 지금 도는 판 번호를 찍는다 (아래 version 명령과 다르다)
|
|
2200
2238
|
|
|
2201
2239
|
딸린 프로그램 — 예전에는 파일 경로로 불렀다. 이제 이름으로 부른다.
|
|
2202
2240
|
인자는 그대로 전달되고, 각각의 사용법은 그 프로그램이 답한다.
|
|
@@ -2219,6 +2257,27 @@ const HELP = `axmap - AI 에이전트 작업 선점 프로토콜
|
|
|
2219
2257
|
const { positional, flags } = parseArgs(process.argv.slice(2))
|
|
2220
2258
|
const [cmd, ...rest] = positional
|
|
2221
2259
|
|
|
2260
|
+
/**
|
|
2261
|
+
* 🔴 `--version` 은 명령이 아니라 **깃발**이라 아래 switch 에 안 걸린다.
|
|
2262
|
+
* 그대로 default 로 떨어져 **도움말을 찍고 종료 코드 0** 을 냈다. 팀 CI 가
|
|
2263
|
+
* "어느 판이 돌았는지" 를 남기려고 넣은 줄이 조용히 쓸모없어졌고, 0 이라
|
|
2264
|
+
* 아무도 못 알아챘다 (실측 2026-09-01, 팀 저장소 .gitlab-ci.yml eb3b56d).
|
|
2265
|
+
*
|
|
2266
|
+
* 🔴 `version` **명령과는 다른 것을 답한다.** 저쪽(tools/version.mjs)은
|
|
2267
|
+
* `process.cwd()` 의 git 태그를 읽는 도구라, 남의 저장소에서 부르면 그
|
|
2268
|
+
* 저장소의 버전이 나온다. 여기가 답해야 하는 것은 "지금 도는 axMap 이 몇
|
|
2269
|
+
* 판인가" 이고, 그 답은 설치본 자기 package.json 에만 있다.
|
|
2270
|
+
*
|
|
2271
|
+
* 못 읽으면 죽는다. 모르는 것을 빈 줄로 내면 CI 로그에는 "판을 확인했다" 는
|
|
2272
|
+
* 흔적만 남고 실제로는 아무것도 확인되지 않는다.
|
|
2273
|
+
*/
|
|
2274
|
+
if (boolFlag(flags.version, 'version') && !cmd) {
|
|
2275
|
+
const v = selfVersion()
|
|
2276
|
+
if (!v) die('버전을 알 수 없습니다 - package.json 이 없는 사본입니다.')
|
|
2277
|
+
console.log(v)
|
|
2278
|
+
process.exit(0)
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2222
2281
|
switch (cmd) {
|
|
2223
2282
|
// 이름을 경로로 바꿔 주는 것들 (RUNNERS). 인자는 손대지 않고 그대로 간다.
|
|
2224
2283
|
case 'setup':
|
|
@@ -2238,6 +2297,9 @@ switch (cmd) {
|
|
|
2238
2297
|
case 'init':
|
|
2239
2298
|
cmdInit(flags)
|
|
2240
2299
|
break
|
|
2300
|
+
case 'bus-repair':
|
|
2301
|
+
cmdBusRepair()
|
|
2302
|
+
break
|
|
2241
2303
|
case 'claim':
|
|
2242
2304
|
cmdClaim(rest, flags)
|
|
2243
2305
|
break
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//name": "🔴 npm 의 'axmap' 은 2022년부터 남이 쓰고 있는 다른 꾸러미다(leozin_ 의 Map 라이브러리, 1.1.2). 그래서 `npx axmap` 은 우리 것이 아니고, 누구에게도 그렇게 안내하면 안 된다. 2026-08-28 에 axmap-cli 로 정했다 — 스코프(@사용자/이름)를 쓰지 않는 이유는 스코프가 npm 계정 이름에 묶여서 나중에 팀이나 조직으로 옮길 때 이름이 통째로 바뀌기 때문이다. 사람이 치는 **명령** 이름은 그대로 axmap 이다 (아래 bin) — 꾸러미 이름과 명령 이름은 달라도 된다.",
|
|
3
3
|
"name": "axmap-cli",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.1",
|
|
5
5
|
"//private": "🔴 여기 있던 \"private\": true 를 2026-08-28 에 지웠다. 그 줄이 있는 동안 npm publish 는 거부됐다. 되돌리려면 다시 넣으면 되지만, 이미 올라간 버전은 그래도 안 사라진다 — npm 은 같은 번호를 덮어쓰지 못하고 삭제도 72시간 안에만 된다. 즉 이 줄을 되살리는 것은 '앞으로 안 올린다' 는 뜻이지 '올린 것을 없앤다' 는 뜻이 아니다.",
|
|
6
6
|
"//publishConfig": "axmap-cli 는 스코프가 없어서 기본이 이미 공개다. 즉 지금은 없어도 된다. 그래도 남겨 두는 이유: 나중에 @조직/axmap 처럼 스코프를 붙이는 날 이 줄이 없으면 publish 가 '유료 플랜이 필요하다'는 엉뚱한 말로 실패한다.",
|
|
7
7
|
"publishConfig": {
|
package/tools/bus.mjs
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* 에 한 줄로 적는 편이 빠르다 — 그건 `axmap status` 로 바로 보인다.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
import { execFileSync } from 'node:child_process'
|
|
33
|
+
import { execFileSync, spawnSync } from 'node:child_process'
|
|
34
34
|
import fs from 'node:fs'
|
|
35
35
|
import path from 'node:path'
|
|
36
36
|
import { fileURLToPath } from 'node:url'
|
|
@@ -114,6 +114,79 @@ function gitBus(argv, opts = {}) {
|
|
|
114
114
|
|
|
115
115
|
const busReady = () => BUS_WT !== null && fs.existsSync(path.join(BUS_WT, '.git'))
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* 쪽지함을 못 연 이유. `null` 이면 정상이다.
|
|
119
|
+
*
|
|
120
|
+
* 🔴 이 변수가 있는 이유는 하나다 — **"쪽지 없음" 과 "못 읽었음" 을 다른 문장으로
|
|
121
|
+
* 내기 위해서다.**
|
|
122
|
+
*
|
|
123
|
+
* 2026-09-03 실측: 원격 `axmap/bus` 에 쪽지 129건이 있고 그중 오늘 온 것이
|
|
124
|
+
* 있는데, 이 체크아웃에 worktree 가 없어서 `pull()` 이 **fetch 를 한 번도 안
|
|
125
|
+
* 하고 조용히 반환**했다. 읽는 자리는 옛 함(`docs/bus`)으로 떨어졌고 거기 있던
|
|
126
|
+
* 8월 것은 이미 읽음이라 화면에 나온 답은 `쪽지 없음.` 이었다. 경고도 없었다.
|
|
127
|
+
*
|
|
128
|
+
* **보내기는 같은 상황에서 제대로 거부했다** (아래 `post`). 쓰기는 막고 읽기만
|
|
129
|
+
* 통과시킨 것이다. 락 시스템에서 최악의 실패는 거부해야 할 것을 조용히
|
|
130
|
+
* 통과시키는 것이고(CLAUDE.md 「애매하면 거부한다」), 쪽지함에서는 **못 읽은
|
|
131
|
+
* 것을 "없다" 고 답하는 것**이 바로 그 자리다. 잘못 막으면 사람이 메시지를
|
|
132
|
+
* 읽고 고치면 되지만, 조용히 없다고 하면 아무도 잘못됐다는 것을 모른다.
|
|
133
|
+
*/
|
|
134
|
+
let busProblem = null
|
|
135
|
+
|
|
136
|
+
/** 옛 함(`docs/bus`)에서만 읽었는가. 새 함을 못 연 채로 성공한 것처럼 보이지 않게 한다. */
|
|
137
|
+
let readFromLegacyOnly = false
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 쪽지함을 연다. **없으면 만든다. 만들었으면 만들었다고 말한다.**
|
|
141
|
+
*
|
|
142
|
+
* 🔴 만드는 코드를 여기에 복사하지 않는다. `bin/axmap.mjs` 의 `ensureBus` 하나뿐이고
|
|
143
|
+
* 이 함수는 그것을 `bus-repair` 로 부른다. 사본을 두면 두 벌이 되고, 두 벌은
|
|
144
|
+
* 반드시 어긋난다 — 이 저장소가 팀 사본을 걷어낸 것과 같은 이유다.
|
|
145
|
+
*
|
|
146
|
+
* 🔴 만들고 나서 **조용히 넘어가지 않는다.** 이 버그의 본질이 "말없이 넘어간 것"
|
|
147
|
+
* 이라, 자동으로 만들어 놓고 또 말없이 넘어가면 증상만 다른 같은 병이 된다.
|
|
148
|
+
* stdout 이 아니라 stderr 로 낸다 — 목록을 파이프로 넘겨도 사람 눈에는 남는다.
|
|
149
|
+
*/
|
|
150
|
+
function openBus() {
|
|
151
|
+
if (process.env.AXMAP_BUS_DIR) return true // 대상이 명시됐으면 물을 것이 없다
|
|
152
|
+
if (busReady()) return true
|
|
153
|
+
if (BUS_WT === null) {
|
|
154
|
+
busProblem = '이 저장소를 찾지 못했습니다.'
|
|
155
|
+
return false
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const r = spawnSync(process.execPath, [path.join(ROOT, 'bin', 'axmap.mjs'), 'bus-repair'], {
|
|
159
|
+
cwd: REPO, encoding: 'utf8', windowsHide: true,
|
|
160
|
+
})
|
|
161
|
+
if (busReady()) {
|
|
162
|
+
console.error(`쪽지함이 없어서 만들었습니다: ${path.join('.axmap', 'bus')} (${BUS_BRANCH})`)
|
|
163
|
+
return true
|
|
164
|
+
}
|
|
165
|
+
busProblem = (r.stderr ?? '').trim() || (r.stdout ?? '').trim() || '알 수 없는 이유로 실패했습니다.'
|
|
166
|
+
return false
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 쪽지함을 못 열었다는 것을 사람이 볼 수 있게 낸다.
|
|
171
|
+
*
|
|
172
|
+
* 🔴 **"없음" 이라고 말하지 않는다.** 받은 쪽지가 없는 것이 아니라 확인을 못 한
|
|
173
|
+
* 것이고, 둘은 사람이 해야 할 일이 정반대다.
|
|
174
|
+
*/
|
|
175
|
+
function reportBusProblem() {
|
|
176
|
+
// 🔴 순서가 뜻이다. **무슨 일인지 먼저, 이유는 그다음.** 이유부터 내면 그것이
|
|
177
|
+
// 여러 줄일 때 안내가 아래로 밀려서, 급한 사람이 첫 줄만 보고 넘어간다.
|
|
178
|
+
const why = busProblem
|
|
179
|
+
.replace(/^경고: /, '')
|
|
180
|
+
.split('\n')
|
|
181
|
+
.map((s, i) => (i === 0 ? s : ` ${s.trim()}`))
|
|
182
|
+
.join('\n')
|
|
183
|
+
console.error(
|
|
184
|
+
'쪽지함을 못 열었습니다 — 받은 쪽지가 없는 것이 아니라 확인을 못 한 것입니다.\n' +
|
|
185
|
+
`\n 이유: ${why}\n` +
|
|
186
|
+
'\n 고치기: axmap bus-repair (MCP 에서는 ax_init)',
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
117
190
|
/**
|
|
118
191
|
* 원격의 쪽지를 받아온다. **실패해도 죽지 않는다** — 못 받은 것은 위험이 아니라
|
|
119
192
|
* 지연이다. 장부(`syncLedger`)가 같은 자리에서 죽는 것과 정반대이고, 그 차이의
|
|
@@ -129,7 +202,10 @@ const busReady = () => BUS_WT !== null && fs.existsSync(path.join(BUS_WT, '.git'
|
|
|
129
202
|
* 쪽지 worktree(`.axmap/bus`) **바깥**이라 고아 브랜치에 섞이지 않는다.
|
|
130
203
|
*/
|
|
131
204
|
function pull() {
|
|
132
|
-
if (!busReady()) return
|
|
205
|
+
// 🔴 예전에는 여기가 `if (!busReady()) return` 이었다. 쪽지함이 없으면 **fetch 를
|
|
206
|
+
// 한 번도 안 하고 조용히 반환**했고, 그것이 "쪽지 없음" 으로 보였다.
|
|
207
|
+
// 이제는 열어 보고, 못 열면 그 사실을 `busProblem` 에 남긴다.
|
|
208
|
+
if (!openBus()) return
|
|
133
209
|
// 🔴 주기는 **설정에서 온다.** `--throttle` 이 1순위(부르는 쪽이 그 자리에서
|
|
134
210
|
// 정한다), 없으면 `AXMAP_BUS_POLL`(초), 그것도 없으면 0 = 매번 받아온다.
|
|
135
211
|
//
|
|
@@ -230,11 +306,17 @@ const slug = (s) => s.toLowerCase().replace(/[^\w가-힣]+/g, '-').replace(/^-|-
|
|
|
230
306
|
|
|
231
307
|
function readAll() {
|
|
232
308
|
const found = []
|
|
309
|
+
let newBoxOpened = false
|
|
233
310
|
for (const box of READ_BOXES) {
|
|
234
311
|
let ns = []
|
|
235
312
|
try { ns = fs.readdirSync(box).filter((f) => f.endsWith('.md')) } catch { continue }
|
|
313
|
+
if (box === BOX) newBoxOpened = true
|
|
236
314
|
for (const f of ns) found.push({ box, f })
|
|
237
315
|
}
|
|
316
|
+
// 🔴 옛 함(`docs/bus`)은 **읽기 전용 유산**이다. 새 함을 못 열었는데 옛 함이
|
|
317
|
+
// 읽히면 지금까지는 그것이 **성공한 것처럼** 보였다 — 8월 20일자 8건이
|
|
318
|
+
// 나오고 오늘 온 쪽지는 없는 것이 된다. 어느 함에서 읽었는지를 남긴다.
|
|
319
|
+
readFromLegacyOnly = !newBoxOpened && found.length > 0
|
|
238
320
|
return found.map(({ box, f }) => {
|
|
239
321
|
const text = fs.readFileSync(path.join(box, f), 'utf8')
|
|
240
322
|
const head = {}
|
|
@@ -419,7 +501,25 @@ function list() {
|
|
|
419
501
|
rows = rows.filter((m) => m.id > seen && m.from !== who)
|
|
420
502
|
}
|
|
421
503
|
|
|
422
|
-
|
|
504
|
+
// 🔴 **못 읽었으면 "없음" 이라고 답하지 않는다.** 이 세 줄이 이 파일에서 제일
|
|
505
|
+
// 중요하다. 나머지는 편의고 이것만이 사고를 막는다.
|
|
506
|
+
//
|
|
507
|
+
// 종료 코드를 0 이 아닌 것으로 낸다 — MCP 서버(`mcp/server.mjs`)는 이미
|
|
508
|
+
// `ok: r.code === 0` 으로 갈라 "쪽지함을 읽지 못했습니다" 를 따로 내도록
|
|
509
|
+
// 되어 있었다. 읽기가 그 신호를 **한 번도 낸 적이 없었을** 뿐이다.
|
|
510
|
+
//
|
|
511
|
+
// `--quiet-if-empty`(훅·배너)일 때만 0 으로 끝낸다. 훅에서 0 이 아니면
|
|
512
|
+
// 커밋이 막히는데, 쪽지를 못 읽은 것으로 커밋을 막는 것은 과하다.
|
|
513
|
+
// **다만 말은 한다** — stderr 는 그 경우에도 그대로 나간다.
|
|
514
|
+
if (busProblem) {
|
|
515
|
+
reportBusProblem()
|
|
516
|
+
if (!has('--quiet-if-empty')) process.exit(1)
|
|
517
|
+
return
|
|
518
|
+
}
|
|
519
|
+
if (!rows.length) {
|
|
520
|
+
if (readFromLegacyOnly) console.error('※ 옛 쪽지함(docs/bus)만 읽었습니다 — 새 쪽지함은 비어 있습니다.')
|
|
521
|
+
return has('--quiet-if-empty') ? undefined : console.log('쪽지 없음.')
|
|
522
|
+
}
|
|
423
523
|
for (const m of rows) {
|
|
424
524
|
console.log(`${m.at?.slice(0, 16).replace('T', ' ')} ${(m.from ?? '?').padEnd(18)} → ${(m.to ?? 'all').padEnd(18)} ${m.subject ?? ''}`)
|
|
425
525
|
console.log(` ${m.id}`)
|
|
@@ -444,6 +544,9 @@ function list() {
|
|
|
444
544
|
function read(id) {
|
|
445
545
|
pull()
|
|
446
546
|
const m = readAll().find((x) => x.id === id || x.id.includes(id))
|
|
547
|
+
// 🔴 못 열었으면 "없는 쪽지" 라고 말하지 않는다. 목록과 같은 이유다 — 사람은
|
|
548
|
+
// 아이디를 잘못 적었다고 믿고 다시 치게 되는데, 몇 번을 쳐도 같은 답이 온다.
|
|
549
|
+
if (!m && busProblem) { reportBusProblem(); process.exit(1) }
|
|
447
550
|
if (!m) { console.error(`없는 쪽지: ${id}`); process.exit(1) }
|
|
448
551
|
console.log(`── ${m.subject}\n ${m.from} → ${m.to} ${m.at}\n`)
|
|
449
552
|
console.log(m.body)
|
|
@@ -491,7 +594,11 @@ switch (cmd) {
|
|
|
491
594
|
case 'post': post({ to: flag('--to'), subject: flag('--subject'), body: stdin() }); break
|
|
492
595
|
case 'reply': {
|
|
493
596
|
const target = args[1]
|
|
597
|
+
// 🔴 답장도 먼저 받아온다. 예전에는 받아오지 않고 찾아서, 원격에만 있는 쪽지에
|
|
598
|
+
// 답장하면 **"없는 쪽지"** 가 나왔다. 아이디를 잘못 적은 것과 구별이 안 된다.
|
|
599
|
+
pull()
|
|
494
600
|
const src = readAll().find((x) => x.id === target || x.id.includes(target))
|
|
601
|
+
if (!src && busProblem) { reportBusProblem(); process.exit(1) }
|
|
495
602
|
if (!src) { console.error(`없는 쪽지: ${target}`); process.exit(1) }
|
|
496
603
|
post({ to: src.from, subject: flag('--subject') ?? `Re: ${src.subject}`, body: stdin(), replyTo: src.id })
|
|
497
604
|
break
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(sed -i 's|/\\\\*\\\\* 궤도 모드에서 허용하는 yaw 한계 \\(약 35°\\). cos 이 0.82 아래로 내려가지 않는다. \\\\*/\\\\nconst YAW_LIMIT = 0.62|X|' app/web/graph.js)",
|
|
5
|
-
"Bash(sed -i 's|const YAW_LIMIT = 0.62|const TILT_LIMIT = 0.62|; s|허용하는 yaw 한계|허용하는 기울기 한계 \\(yaw · pitch 공통\\)|' app/web/graph.js)",
|
|
6
|
-
"Bash(sed -i 's|인코딩은 인코딩이 아니다. cos\\(TILT_LIMIT\\)=0.82 이면 고리의 화면 반지름이\\\\n \\\\* \\\\[0.82R, R\\\\] 안에 머물러 이웃 단계와 절대 겹치지 않는다.|X|' app/web/graph.js)",
|
|
7
|
-
"Bash(sed -n '/인코딩은 인코딩이 아니다/,+2p' app/web/graph.js)",
|
|
8
|
-
"Bash(sed -i 's|import { applyEdits, draft, editRecord } from|import { applyEdits, draft } from|' app/server.mjs)",
|
|
9
|
-
"Bash(sed -i 's|\"test\": \"node --test test/protocol.test.mjs test/model.test.mjs test/analyze.test.mjs\"|\"test\": \"node --test test/protocol.test.mjs test/model.test.mjs test/analyze.test.mjs test/features.test.mjs\"|' package.json)",
|
|
10
|
-
"Bash(npm test *)",
|
|
11
|
-
"Bash(sed -i 's| .filter\\(\\(\\\\[t\\\\]\\) => t !== name \\\\&\\\\& !taken.has\\(t\\)\\)| .filter\\(\\([t]\\) => t !== name \\\\&\\\\& !taken.has\\(t\\) \\\\&\\\\& !tooCommon\\(t\\)\\)|' app/lib/features.mjs)",
|
|
12
|
-
"Bash(node -e ' *)",
|
|
13
|
-
"Bash(npm run *)",
|
|
14
|
-
"Bash(export AXMAP_AGENT=claude-fix GIT_AUTHOR_NAME=claude-fix GIT_AUTHOR_EMAIL=claude-fix@local GIT_COMMITTER_NAME=claude-fix GIT_COMMITTER_EMAIL=claude-fix@local)",
|
|
15
|
-
"Bash(node bin/axmap.mjs claim app/web/app.js app/web/graph.js app/web/style.css --task fix-click-color --intent \"이름 클릭=강조/더블클릭=이름변경, 단계 없을 때 색 회귀 수정\" --actor agent)",
|
|
16
|
-
"Bash(sed 's/\\\\$$//')",
|
|
17
|
-
"Bash(python -)",
|
|
18
|
-
"Bash(sed -n '/import 를 뽑을 수 있는 언어 이름/,/^\\\\]\\)/p' app/lib/analyze.mjs)",
|
|
19
|
-
"Bash(export AXMAP_AGENT=janghyojoon)",
|
|
20
|
-
"Bash(node bin/axmap.mjs release)",
|
|
21
|
-
"Bash(echo \"// 테스트\")",
|
|
22
|
-
"Bash(git add *)",
|
|
23
|
-
"Bash(git commit *)",
|
|
24
|
-
"Bash(git reset *)",
|
|
25
|
-
"Bash(git checkout *)"
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
"enabledMcpjsonServers": [
|
|
29
|
-
"axmap"
|
|
30
|
-
],
|
|
31
|
-
"enableAllProjectMcpServers": true
|
|
32
|
-
}
|