leerness 1.9.210 โ 1.9.211
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/CHANGELOG.md +53 -0
- package/README.md +3 -3
- package/bin/harness.js +259 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.211 โ 2026-05-22
|
|
4
|
+
|
|
5
|
+
**๐ `.harness` โ `.leerness` opt-in ๋ง์ด๊ทธ๋ ์ด์
+ AI ์ฐธ์กฐ ๊ฐ์ด๋ (์ฌ์ฉ์ ๋ช
์).**
|
|
6
|
+
|
|
7
|
+
### ์ฌ์ฉ์ ๋ช
์
|
|
8
|
+
> *"leerness์ค์น์ ์์ฑ๋๋ .harness๋ฅผ .leerness์ผ๋ก ๋ณ๊ฒฝํ ์ ์์๊น / ๊ธฐ์กด ๋ฒ์ ์์๋ ๋ง์ด๊ทธ๋ ์ด์
์ AI๊ฐ ์ฐธ์กฐํ ์ ์๊ธฐ๋ํ๋ฉด ์ด๋จ๊น"*
|
|
9
|
+
|
|
10
|
+
### 1. workspace-dir ํฌํผ (default-safe opt-in)
|
|
11
|
+
- `_workspaceDirName(root)` โ env `LEERNESS_WORKSPACE_DIR` > `.leerness/MIGRATED_FROM_HARNESS` ๋ง์ปค > default `.harness`
|
|
12
|
+
- `_workspaceDirAbs(root)` โ ์ ๋ ๊ฒฝ๋ก
|
|
13
|
+
- ๊ธฐ๋ณธ ๋์: **`.harness` ์ ์ง** (226+ path reference ์์ ) โ breaking change 0
|
|
14
|
+
|
|
15
|
+
### 2. ๋ง์ด๊ทธ๋ ์ด์
์์คํ
|
|
16
|
+
- `_migrateWorkspaceDir(root, opts)` โ `.harness` ์ ์ฒด ์ฌ๊ท copy โ `.leerness`
|
|
17
|
+
ยท `--dry-run` ์ง์
|
|
18
|
+
ยท `--force` (๊ธฐ์กด dst ๋ฎ์ด์ฐ๊ธฐ)
|
|
19
|
+
ยท skip / errors / copiedFiles ๋ถ๋ฅ ๋ณด๊ณ
|
|
20
|
+
- ๋ง์ด๊ทธ๋ ์ด์
๊ฒฐ๊ณผ๋ฌผ:
|
|
21
|
+
ยท `.leerness/MIGRATED_FROM_HARNESS` ๋ง์ปค
|
|
22
|
+
ยท `.leerness/WHERE_TO_FIND.md` AI ์ฐธ์กฐ ๊ฐ์ด๋ (์๋ ์์ฑ)
|
|
23
|
+
ยท `.harness/MIGRATED_TO_LEERNESS.md` redirect ์๋ด (backward compat ์ ์ง)
|
|
24
|
+
|
|
25
|
+
### 3. AI ์ฐธ์กฐ ๊ฐ์ด๋ (`_buildWorkspaceReferenceGuide`)
|
|
26
|
+
- ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ ์๊ฐํ (ํต์ฌ ํ์ผ 25๊ฐ)
|
|
27
|
+
- "์์ฃผ ๋ฌป๋ ์์น" ๋งคํ ํ (ํ์ฌ task / ์๊ตฌ ๋ฃฐ / pre-wake / ๋ฏธ๋ต ์์ฒญ / ๋ค์ ๋ผ์ด๋ plan / API ์ ์ฝ / wakeup ๊ถ์ฅ)
|
|
28
|
+
- ๋ง์ด๊ทธ๋ ์ด์
์๋ด (3๊ฐ์ง ์ํ ๋ถ๊ธฐ)
|
|
29
|
+
- 1.9.207~210 ์ ๊ท ๋ฉํํ์ผ ์์น ๋ช
์
|
|
30
|
+
|
|
31
|
+
### 4. `leerness workspace-dir <get|guide>` CLI
|
|
32
|
+
- `get` โ ํ์ฌ ๋๋ ํ ๋ฆฌ + .harness/.leerness ์กด์ฌ ์ฌ๋ถ + ๋ง์ด๊ทธ๋ ์ด์
์ํ
|
|
33
|
+
- `guide` โ AI ์ฐธ์กฐ ๊ฐ์ด๋ ์ถ๋ ฅ
|
|
34
|
+
|
|
35
|
+
### 5. `leerness migrate-workspace-dir` CLI
|
|
36
|
+
- `--dry-run` / `--force` ์ง์
|
|
37
|
+
- copied / skipped / errors ๋ถ๋ฅ
|
|
38
|
+
- ์๋ ๋ง์ปค + ๊ฐ์ด๋ + redirect ์์ฑ
|
|
39
|
+
|
|
40
|
+
### 6. ๋์ ํ๊ท (1.9.200~210) โ ๋ชจ๋ ์ ์ง
|
|
41
|
+
|
|
42
|
+
### 7. stress-v156 โ 19/19 PASS
|
|
43
|
+
- 1.9.211 (10) + ์ฑ๋ฅ (2) + ๋์ ํ๊ท (7)
|
|
44
|
+
- ๊ฒฉ๋ฆฌ tmp dir ์ ์ฒด ์ฌ์ดํด (default โ dry-run โ migrate โ auto-detect โ env override)
|
|
45
|
+
- AI ๊ฐ์ด๋ ํค ์น์
๊ฒ์ฆ
|
|
46
|
+
- ์ฑ๋ฅ: --version cold start avg 452ms ยท MCP 54 ๋๊ตฌ 445ms
|
|
47
|
+
|
|
48
|
+
### 8. ์๋ release (73 ๋ผ์ด๋ main-push streak ยท 34 ๋ผ์ด๋ npm publish streak)
|
|
49
|
+
|
|
50
|
+
### 9. ํ์ ๋ผ์ด๋ ๋ก๋๋งต
|
|
51
|
+
- ์ด๋ฒ ๋ผ์ด๋๋ **opt-in ํฌํผ + CLI**๋ง ์ถ๊ฐ (breaking change 0)
|
|
52
|
+
- ํ์์์ 226+ path reference ๋ฅผ `_workspaceDirAbs(root)` ๋ก ์ ์ง ์ ํ
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
3
56
|
## 1.9.210 โ 2026-05-22
|
|
4
57
|
|
|
5
58
|
**โก adaptive wakeup interval โ ์ฌ์ฉ์ ํ๋ ๊ธฐ๋ฐ ์๋ ์กฐ์ (์ฌ์ฉ์ ๋ช
์).**
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **AI ์ฝ๋ฉ ์์ด์ ํธ์ ๊ฑฐ์ง ์๋ฃยท์ค๋ณตยท๋ง๊ฐยท์ถฉ๋์ ๋ง์์ฃผ๋ ๊ฒ์ยท๊ธฐ์ตยทํ์
CLI ํ๋ค์ค.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []() [-brightgreen)]() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
โ โโโ โโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโ โ
|
|
13
13
|
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
|
|
14
14
|
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโ โ
|
|
15
|
-
โ v1.9.
|
|
15
|
+
โ v1.9.211 AI Agent Reliability Harness + Sandbox โ
|
|
16
16
|
โ verify ยท remember ยท orchestrate ยท audit ยท sandbox ยท drift โ
|
|
17
|
-
โ
|
|
17
|
+
โ ๐ .harness โ .leerness opt-in ๋ง์ด๊ทธ๋ ์ด์
(์ฌ์ฉ์ ๋ช
์) โ
|
|
18
18
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
19
19
|
```
|
|
20
20
|
|
package/bin/harness.js
CHANGED
|
@@ -7,7 +7,7 @@ const cp = require('child_process');
|
|
|
7
7
|
const os = require('os'); // 1.9.178: _publishToNpm ์์ os.tmpdir() ์ฌ์ฉ (์ ์ญ import)
|
|
8
8
|
const readline = require('readline');
|
|
9
9
|
|
|
10
|
-
const VERSION = '1.9.
|
|
10
|
+
const VERSION = '1.9.211';
|
|
11
11
|
|
|
12
12
|
// 1.9.184: DEP0190 (child_process shell: true) deprecation warning ์ต์ (์ฌ์ฉ์ ๋ช
์).
|
|
13
13
|
// leerness ๋ cross-platform PATH resolution ์ ์ํด shell: true ๋ฅผ ์๋์ ์ผ๋ก ์ฌ์ฉ (claude.cmd / ollama.cmd ๋ฑ Windows .cmd ์ฒ๋ฆฌ).
|
|
@@ -2364,6 +2364,168 @@ function _computeAdaptiveInterval(root) {
|
|
|
2364
2364
|
};
|
|
2365
2365
|
}
|
|
2366
2366
|
|
|
2367
|
+
// 1.9.211: .harness โ .leerness rename + migration + AI ์ฐธ์กฐ ๊ฐ์ด๋ (์ฌ์ฉ์ ๋ช
์)
|
|
2368
|
+
// "leerness์ค์น์ ์์ฑ๋๋ .harness๋ฅผ .leerness์ผ๋ก ๋ณ๊ฒฝํ ์ ์์๊น / ๊ธฐ์กด ๋ฒ์ ์์๋ ๋ง์ด๊ทธ๋ ์ด์
์ AI๊ฐ ์ฐธ์กฐํ ์ ์๊ธฐ๋ํ๋ฉด ์ด๋จ๊น"
|
|
2369
|
+
// ์ ๊ทผ ๋ฐฉ์: opt-in ๋ง์ด๊ทธ๋ ์ด์
(breaking change ์ต์ํ)
|
|
2370
|
+
// - default: .harness ์ ์ง (226+ path reference ์์ )
|
|
2371
|
+
// - LEERNESS_WORKSPACE_DIR env ๋๋ .leerness/MARKER ์กด์ฌ ์ .leerness ์ฌ์ฉ
|
|
2372
|
+
// - leerness migrate-workspace-dir CLI: .harness โ .leerness copy + AI reference guide ์์ฑ
|
|
2373
|
+
// - AI ์ฐธ์กฐ ๊ฐ์ด๋: WHERE_TO_FIND.md (๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ + ํ์ผ๋ณ ์ญํ + ๋ง์ด๊ทธ๋ ์ด์
history)
|
|
2374
|
+
function _workspaceDirName(root) {
|
|
2375
|
+
// 1) env override
|
|
2376
|
+
if (process.env.LEERNESS_WORKSPACE_DIR) {
|
|
2377
|
+
const v = process.env.LEERNESS_WORKSPACE_DIR.trim();
|
|
2378
|
+
if (v) return v;
|
|
2379
|
+
}
|
|
2380
|
+
// 2) .leerness ๋ง์ด๊ทธ๋ ์ด์
๋ง์ปค ์กด์ฌ ์ .leerness ์ฐ์
|
|
2381
|
+
try {
|
|
2382
|
+
if (root && exists(path.join(root, '.leerness', 'MIGRATED_FROM_HARNESS'))) {
|
|
2383
|
+
return '.leerness';
|
|
2384
|
+
}
|
|
2385
|
+
} catch {}
|
|
2386
|
+
// 3) default
|
|
2387
|
+
return '.harness';
|
|
2388
|
+
}
|
|
2389
|
+
function _workspaceDirAbs(root) {
|
|
2390
|
+
return path.join(root, _workspaceDirName(root));
|
|
2391
|
+
}
|
|
2392
|
+
// .harness โ .leerness ๋ง์ด๊ทธ๋ ์ด์
(copy + reference guide ์์ฑ)
|
|
2393
|
+
function _migrateWorkspaceDir(root, opts = {}) {
|
|
2394
|
+
const dryRun = opts.dryRun === true;
|
|
2395
|
+
const srcDir = path.join(root, '.harness');
|
|
2396
|
+
const dstDir = path.join(root, '.leerness');
|
|
2397
|
+
const report = {
|
|
2398
|
+
at: new Date().toISOString(),
|
|
2399
|
+
version: VERSION,
|
|
2400
|
+
src: srcDir,
|
|
2401
|
+
dst: dstDir,
|
|
2402
|
+
srcExists: exists(srcDir),
|
|
2403
|
+
dstExists: exists(dstDir),
|
|
2404
|
+
copiedFiles: [],
|
|
2405
|
+
skippedFiles: [],
|
|
2406
|
+
errors: [],
|
|
2407
|
+
dryRun
|
|
2408
|
+
};
|
|
2409
|
+
if (!report.srcExists) {
|
|
2410
|
+
report.errors.push('source .harness not found');
|
|
2411
|
+
return report;
|
|
2412
|
+
}
|
|
2413
|
+
if (!dryRun) {
|
|
2414
|
+
mkdirp(dstDir);
|
|
2415
|
+
}
|
|
2416
|
+
// ์ฌ๊ท copy ํฌํผ
|
|
2417
|
+
function copyRec(rel) {
|
|
2418
|
+
const srcAbs = path.join(srcDir, rel);
|
|
2419
|
+
const dstAbs = path.join(dstDir, rel);
|
|
2420
|
+
let stat;
|
|
2421
|
+
try { stat = fs.statSync(srcAbs); } catch (e) { report.errors.push(`stat ${rel}: ${e.message}`); return; }
|
|
2422
|
+
if (stat.isDirectory()) {
|
|
2423
|
+
if (!dryRun) mkdirp(dstAbs);
|
|
2424
|
+
let entries;
|
|
2425
|
+
try { entries = fs.readdirSync(srcAbs); } catch (e) { report.errors.push(`readdir ${rel}: ${e.message}`); return; }
|
|
2426
|
+
for (const e of entries) copyRec(path.join(rel, e));
|
|
2427
|
+
} else if (stat.isFile()) {
|
|
2428
|
+
// ๊ธฐ์กด dst ํ์ผ์ด ์๊ณ ์ฐ๋ฆฌ๊ฐ force๊ฐ ์๋๋ฉด skip
|
|
2429
|
+
if (exists(dstAbs) && !opts.force) {
|
|
2430
|
+
report.skippedFiles.push(rel);
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
if (!dryRun) {
|
|
2434
|
+
try {
|
|
2435
|
+
fs.copyFileSync(srcAbs, dstAbs);
|
|
2436
|
+
report.copiedFiles.push(rel);
|
|
2437
|
+
} catch (e) {
|
|
2438
|
+
report.errors.push(`copy ${rel}: ${e.message}`);
|
|
2439
|
+
}
|
|
2440
|
+
} else {
|
|
2441
|
+
report.copiedFiles.push(rel);
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
copyRec('');
|
|
2446
|
+
// ๋ง์ด๊ทธ๋ ์ด์
๋ง์ปค + AI ์ฐธ์กฐ ๊ฐ์ด๋ ์์ฑ
|
|
2447
|
+
if (!dryRun) {
|
|
2448
|
+
const marker = `Migrated from .harness at ${report.at} by leerness ${VERSION}\n`;
|
|
2449
|
+
try { writeUtf8(path.join(dstDir, 'MIGRATED_FROM_HARNESS'), marker); } catch (e) { report.errors.push(`marker: ${e.message}`); }
|
|
2450
|
+
const guide = _buildWorkspaceReferenceGuide(root, '.leerness');
|
|
2451
|
+
try { writeUtf8(path.join(dstDir, 'WHERE_TO_FIND.md'), guide); } catch (e) { report.errors.push(`guide: ${e.message}`); }
|
|
2452
|
+
// .harness ์๋ redirect ์๋ด ์ถ๊ฐ (AI๊ฐ .harness ๋จผ์ ๋ด๋ .leerness ๋ก ๊ฐ๊ฒ)
|
|
2453
|
+
try {
|
|
2454
|
+
const redirect = `# .harness โ .leerness migration (${report.at})\n\n` +
|
|
2455
|
+
`์ด ์ํฌ์คํ์ด์ค๋ \`.harness\` โ \`.leerness\` ๋ก ๋ง์ด๊ทธ๋ ์ด์
๋์์ต๋๋ค (leerness ${VERSION}).\n\n` +
|
|
2456
|
+
`**AI ์์ด์ ํธ๋ ${'.leerness/'} ๋๋ ํ ๋ฆฌ๋ฅผ ์ฐ์ ์ฐธ์กฐํ์ญ์์ค.**\n\n` +
|
|
2457
|
+
`- ์ ๊ท ๋ฉํํ์ผ ์์น: \`.leerness/\`\n` +
|
|
2458
|
+
`- ์ฐธ์กฐ ๊ฐ์ด๋: \`.leerness/WHERE_TO_FIND.md\`\n` +
|
|
2459
|
+
`- ๋ง์ด๊ทธ๋ ์ด์
๋ง์ปค: \`.leerness/MIGRATED_FROM_HARNESS\`\n\n` +
|
|
2460
|
+
`\`.harness/\` ๋ backward compatibility ๋ฅผ ์ํด ๋ณด์กด๋ฉ๋๋ค (read-only ๊ถ์ฅ).\n`;
|
|
2461
|
+
writeUtf8(path.join(srcDir, 'MIGRATED_TO_LEERNESS.md'), redirect);
|
|
2462
|
+
} catch (e) { report.errors.push(`redirect: ${e.message}`); }
|
|
2463
|
+
}
|
|
2464
|
+
return report;
|
|
2465
|
+
}
|
|
2466
|
+
// AI ์ฐธ์กฐ ๊ฐ์ด๋ ๋น๋ โ ์ํฌ์คํ์ด์ค ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ + ํ์ผ๋ณ ์ญํ ๋งคํ
|
|
2467
|
+
function _buildWorkspaceReferenceGuide(root, dirName) {
|
|
2468
|
+
const lines = [];
|
|
2469
|
+
lines.push(`# Leerness Workspace Reference Guide`);
|
|
2470
|
+
lines.push('');
|
|
2471
|
+
lines.push(`> AI ์์ด์ ํธ๊ฐ leerness ์ํฌ์คํ์ด์ค์์ ์ด๋ค ํ์ผ์ ์ด๋์ ์ฐพ๋์ง ์๋ดํฉ๋๋ค (1.9.211).`);
|
|
2472
|
+
lines.push('');
|
|
2473
|
+
lines.push(`Generated: ${new Date().toISOString()} by leerness ${VERSION}`);
|
|
2474
|
+
lines.push(`Workspace dir: \`${dirName}/\``);
|
|
2475
|
+
lines.push('');
|
|
2476
|
+
lines.push(`## ๐ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ (ํต์ฌ)`);
|
|
2477
|
+
lines.push('');
|
|
2478
|
+
lines.push('```');
|
|
2479
|
+
lines.push(`${dirName}/`);
|
|
2480
|
+
lines.push(`โโโ plan.md โ ๋ฌด์์ ํ ๊ฒ์ธ๊ฐ (์ฌ์ฉ์ ๋ฉ๋ชจ๋ฆฌ)`);
|
|
2481
|
+
lines.push(`โโโ progress-tracker.md โ ๋ฌด์์ ํ๋๊ฐ (์ฆ๊ฑฐ ํฌํจ, ์ฌ์ฉ์ ๋ฉ๋ชจ๋ฆฌ)`);
|
|
2482
|
+
lines.push(`โโโ decisions.md โ ์ ๊ทธ๋ ๊ฒ ํ๋๊ฐ (์ฌ์ฉ์ ๋ฉ๋ชจ๋ฆฌ)`);
|
|
2483
|
+
lines.push(`โโโ session-handoff.md โ ๋ค์ ์ธ์
์ธ๊ณ (์ฌ์ฉ์ ๋ฉ๋ชจ๋ฆฌ)`);
|
|
2484
|
+
lines.push(`โโโ lessons.md โ ๊ณผ๊ฑฐ ๊ตํ (์๋ fuzzy ํ์)`);
|
|
2485
|
+
lines.push(`โโโ rules.md โ ์์ฐ์ด ๋ฃฐ (๋งค ์ธ์
์๋ ๋
ธ์ถ, R-XXXX)`);
|
|
2486
|
+
lines.push(`โโโ task-log.md โ in-progress / dropped task ์ด๋ ฅ`);
|
|
2487
|
+
lines.push(`โโโ reuse-map.md โ ์ํฌ์คํ์ด์ค capability ๋งคํ`);
|
|
2488
|
+
lines.push(`โโโ skill-suggestions.md โ skill rolling history`);
|
|
2489
|
+
lines.push(`โโโ feature-graph.md โ ๊ธฐ๋ฅ ์์กด ๊ทธ๋ํ (F-XXXX)`);
|
|
2490
|
+
lines.push(`โโโ manifest.json โ ์ํฌ์คํ์ด์ค ๋ฉํ`);
|
|
2491
|
+
lines.push(`โโโ leerness-config.json โ ๋น์ํฌ๋ฆฟ LEERNESS_* ์ค์ (1.9.187, AI ๊ฐ์)`);
|
|
2492
|
+
lines.push(`โโโ user-requests.json โ ์ฌ์ฉ์ ๋ช
์ ์์ฒญ ๋์ (1.9.207)`);
|
|
2493
|
+
lines.push(`โโโ active-wakeups.json โ ScheduleWakeup ์ํ (1.9.205)`);
|
|
2494
|
+
lines.push(`โโโ pre-wake-report.json โ sleep ์ sub-agent audit (1.9.209)`);
|
|
2495
|
+
lines.push(`โโโ wakeup-history.json โ adaptive wakeup ์ด๋ ฅ (1.9.210)`);
|
|
2496
|
+
lines.push(`โโโ platform-constraints.json โ API ์ ์ฝ catalog (1.9.208)`);
|
|
2497
|
+
lines.push(`โโโ auto-resume-plan.json โ ๋ค์ ๋ผ์ด๋ plan (1.9.203)`);
|
|
2498
|
+
lines.push(`โโโ next-action-queue.json โ ๋ค์ next-action ํ (1.9.201)`);
|
|
2499
|
+
lines.push(`โโโ last-handoff.json โ ๋ง์ง๋ง handoff timestamp`);
|
|
2500
|
+
lines.push(`โโโ environment.json โ ํ๊ฒฝ ๋ณ๋ ์ถ์ (1.9.145)`);
|
|
2501
|
+
lines.push(`โโโ skills/ โ ์ค์น๋ skill ๋๋ ํ ๋ฆฌ`);
|
|
2502
|
+
lines.push(`โโโ templates/ โ ์ํฌ์คํ์ด์ค ํ
ํ๋ฆฟ`);
|
|
2503
|
+
lines.push('```');
|
|
2504
|
+
lines.push('');
|
|
2505
|
+
lines.push(`## ๐งญ ์์ฃผ ๋ฌป๋ ์์น`);
|
|
2506
|
+
lines.push('');
|
|
2507
|
+
lines.push(`| ์ฐพ๋ ๊ฒ | ์์น |`);
|
|
2508
|
+
lines.push(`|---|---|`);
|
|
2509
|
+
lines.push(`| ํ์ฌ ์งํ ์ค์ธ task | \`${dirName}/progress-tracker.md\` (status: in-progress) |`);
|
|
2510
|
+
lines.push(`| ์ฌ์ฉ์๊ฐ ๋ช
์ํ ์๊ตฌ ๋ฃฐ | \`${dirName}/rules.md\` (active R-XXXX) |`);
|
|
2511
|
+
lines.push(`| ์ง์ sleep ์ audit ๊ฒฐ๊ณผ | \`${dirName}/pre-wake-report.json\` (1.9.209) |`);
|
|
2512
|
+
lines.push(`| ๋ฏธ๋ต ์ฌ์ฉ์ ์์ฒญ | \`${dirName}/user-requests.json\` (status: open) |`);
|
|
2513
|
+
lines.push(`| ๋ค์ ๋ผ์ด๋ ๊ถ์ฅ ๋จ๊ณ | \`${dirName}/auto-resume-plan.json\` (1.9.203) |`);
|
|
2514
|
+
lines.push(`| API ์ ์ฝ catalog | \`${dirName}/platform-constraints.json\` (1.9.208) |`);
|
|
2515
|
+
lines.push(`| ์๋ wakeup ๊ถ์ฅ ๊ฐ๊ฒฉ | \`${dirName}/wakeup-history.json\` (1.9.210) |`);
|
|
2516
|
+
lines.push('');
|
|
2517
|
+
lines.push(`## ๐ ๋ง์ด๊ทธ๋ ์ด์
์๋ด`);
|
|
2518
|
+
lines.push('');
|
|
2519
|
+
lines.push(`์ด ์ํฌ์คํ์ด์ค๋ \`.harness\` โ \`.leerness\` ๋ก ๋ง์ด๊ทธ๋ ์ด์
๋์์ ์ ์์ต๋๋ค.`);
|
|
2520
|
+
lines.push(`- \`.leerness/MIGRATED_FROM_HARNESS\` ์กด์ฌ โ ๋ง์ด๊ทธ๋ ์ด์
์๋ฃ, \`.leerness\` ์ฐ์ ์ฌ์ฉ`);
|
|
2521
|
+
lines.push(`- \`.harness/MIGRATED_TO_LEERNESS.md\` ์กด์ฌ โ \`.leerness/\` ๋ก ๊ฐ์ผ ํจ`);
|
|
2522
|
+
lines.push(`- ์์ชฝ ๋ชจ๋ ์์ โ ๊ธฐ๋ณธ \`.harness\` ์ฌ์ฉ ์ค`);
|
|
2523
|
+
lines.push('');
|
|
2524
|
+
lines.push(`AI ์์ด์ ํธ๋ \`leerness handoff .\` ๊ฒฐ๊ณผ๋ฅผ ์ ๋ขฐํ์ญ์์ค โ ์๋์ผ๋ก ์ฌ๋ฐ๋ฅธ ๋๋ ํ ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.`);
|
|
2525
|
+
lines.push('');
|
|
2526
|
+
return lines.join('\n');
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2367
2529
|
// 1.9.203: ์๋ ๋ผ์ด๋ plan ์ ๋ฆฌ โ ์ฌ์ฉ์ ๋ช
์
|
|
2368
2530
|
// "๋ฐฑ๊ทธ๋ผ์ด๋์ ๋ค์ ์์
์ด ์์๊ฐ๋ฅํ ์์ ์๊ฐ + ์ผ์ด๋ฌ์๋ ํด์ผํ๋ ์ผ์ ์ ๋ฆฌ"
|
|
2369
2531
|
// ๋ผ์ด๋ ๋ง๋ฌด๋ฆฌ ์ .harness/auto-resume-plan.json ์๋ ์ ์ฅ โ ๋ค์ wakeup ์ ์ฆ์ ์คํ ๊ฐ๋ฅ
|
|
@@ -2875,6 +3037,98 @@ function wakeupIntervalCmd(root, sub, val) {
|
|
|
2875
3037
|
process.exit(1);
|
|
2876
3038
|
}
|
|
2877
3039
|
|
|
3040
|
+
// 1.9.211: leerness workspace-dir <get|guide> โ ์ํฌ์คํ์ด์ค ๋๋ ํ ๋ฆฌ ์ ๋ณด + AI ์ฐธ์กฐ ๊ฐ์ด๋ (์ฌ์ฉ์ ๋ช
์)
|
|
3041
|
+
function workspaceDirCmd(root, sub) {
|
|
3042
|
+
root = absRoot(root);
|
|
3043
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
3044
|
+
const cyan = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
3045
|
+
const grn = s => isTty ? `\x1b[32m${s}\x1b[0m` : s;
|
|
3046
|
+
const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
3047
|
+
|
|
3048
|
+
if (!sub || sub === 'get') {
|
|
3049
|
+
const dirName = _workspaceDirName(root);
|
|
3050
|
+
const dirAbs = _workspaceDirAbs(root);
|
|
3051
|
+
const hasHarness = exists(path.join(root, '.harness'));
|
|
3052
|
+
const hasLeerness = exists(path.join(root, '.leerness'));
|
|
3053
|
+
const migrated = exists(path.join(root, '.leerness', 'MIGRATED_FROM_HARNESS'));
|
|
3054
|
+
const result = { current: dirName, abs: dirAbs, hasHarness, hasLeerness, migrated };
|
|
3055
|
+
if (has('--json')) { log(JSON.stringify(result, null, 2)); return; }
|
|
3056
|
+
log(cyan(`# leerness workspace-dir (1.9.211)`));
|
|
3057
|
+
log(` ํ์ฌ ๋๋ ํ ๋ฆฌ: ${grn(dirName + '/')}`);
|
|
3058
|
+
log(` abs: ${dirAbs}`);
|
|
3059
|
+
log(` .harness ์กด์ฌ: ${hasHarness ? 'โ' : 'โ'}`);
|
|
3060
|
+
log(` .leerness ์กด์ฌ: ${hasLeerness ? 'โ' : 'โ'}`);
|
|
3061
|
+
log(` ๋ง์ด๊ทธ๋ ์ด์
์๋ฃ: ${migrated ? 'โ' : 'โ'}`);
|
|
3062
|
+
log('');
|
|
3063
|
+
if (hasHarness && !hasLeerness) {
|
|
3064
|
+
log(dim(` โ ๋ง์ด๊ทธ๋ ์ด์
: leerness migrate-workspace-dir`));
|
|
3065
|
+
} else if (migrated) {
|
|
3066
|
+
log(dim(` โ AI ์ฐธ์กฐ ๊ฐ์ด๋: leerness workspace-dir guide`));
|
|
3067
|
+
}
|
|
3068
|
+
return;
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
if (sub === 'guide') {
|
|
3072
|
+
const dirName = _workspaceDirName(root);
|
|
3073
|
+
const guide = _buildWorkspaceReferenceGuide(root, dirName);
|
|
3074
|
+
if (has('--json')) { log(JSON.stringify({ workspaceDir: dirName, guide }, null, 2)); return; }
|
|
3075
|
+
log(guide);
|
|
3076
|
+
return;
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
console.error(`Usage: leerness workspace-dir [get|guide]`);
|
|
3080
|
+
process.exit(1);
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
// 1.9.211: leerness migrate-workspace-dir โ .harness โ .leerness ๋ง์ด๊ทธ๋ ์ด์
(์ฌ์ฉ์ ๋ช
์)
|
|
3084
|
+
function migrateWorkspaceDirCmd(root) {
|
|
3085
|
+
root = absRoot(root);
|
|
3086
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
3087
|
+
const cyan = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
3088
|
+
const grn = s => isTty ? `\x1b[32m${s}\x1b[0m` : s;
|
|
3089
|
+
const yel = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
|
|
3090
|
+
const red = s => isTty ? `\x1b[31m${s}\x1b[0m` : s;
|
|
3091
|
+
const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
3092
|
+
|
|
3093
|
+
const dryRun = has('--dry-run');
|
|
3094
|
+
const force = has('--force');
|
|
3095
|
+
const report = _migrateWorkspaceDir(root, { dryRun, force });
|
|
3096
|
+
|
|
3097
|
+
if (has('--json')) { log(JSON.stringify(report, null, 2)); return; }
|
|
3098
|
+
log(cyan(`# leerness migrate-workspace-dir (1.9.211)${dryRun ? ' [DRY-RUN]' : ''}`));
|
|
3099
|
+
log(` src: ${report.src} ${report.srcExists ? 'โ' : red('โ ์์')}`);
|
|
3100
|
+
log(` dst: ${report.dst} ${report.dstExists ? yel('โ ์ด๋ฏธ ์กด์ฌ') : '(์์ฑ)'}`);
|
|
3101
|
+
log('');
|
|
3102
|
+
log(` ๐ copied: ${grn(report.copiedFiles.length)}, skipped: ${report.skippedFiles.length}, errors: ${report.errors.length}`);
|
|
3103
|
+
if (report.copiedFiles.length > 0 && report.copiedFiles.length <= 30) {
|
|
3104
|
+
log('');
|
|
3105
|
+
log(` ๋ณต์ฌ๋ ํ์ผ:`);
|
|
3106
|
+
report.copiedFiles.slice(0, 20).forEach(f => log(dim(` + ${f}`)));
|
|
3107
|
+
if (report.copiedFiles.length > 20) log(dim(` ... +${report.copiedFiles.length - 20}๊ฑด`));
|
|
3108
|
+
} else if (report.copiedFiles.length > 30) {
|
|
3109
|
+
log(dim(` (${report.copiedFiles.length}๊ฐ โ ์์ธ๋ --json)`));
|
|
3110
|
+
}
|
|
3111
|
+
if (report.skippedFiles.length > 0) {
|
|
3112
|
+
log('');
|
|
3113
|
+
log(yel(` ์คํต๋ ํ์ผ (์ด๋ฏธ ์กด์ฌ, --force ๋ก ๋ฎ์ด์ฐ๊ธฐ ๊ฐ๋ฅ):`));
|
|
3114
|
+
report.skippedFiles.slice(0, 5).forEach(f => log(dim(` - ${f}`)));
|
|
3115
|
+
if (report.skippedFiles.length > 5) log(dim(` ... +${report.skippedFiles.length - 5}๊ฑด`));
|
|
3116
|
+
}
|
|
3117
|
+
if (report.errors.length > 0) {
|
|
3118
|
+
log('');
|
|
3119
|
+
log(red(` โ ์๋ฌ:`));
|
|
3120
|
+
report.errors.forEach(e => log(red(` - ${e}`)));
|
|
3121
|
+
}
|
|
3122
|
+
log('');
|
|
3123
|
+
if (!dryRun && report.copiedFiles.length > 0) {
|
|
3124
|
+
log(grn(`โ ๋ง์ด๊ทธ๋ ์ด์
์๋ฃ โ .leerness/WHERE_TO_FIND.md + MIGRATED_FROM_HARNESS ๋ง์ปค ์์ฑ`));
|
|
3125
|
+
log(dim(` โ ๋ค์ handoff๋ถํฐ .leerness ์ฐ์ ์ฌ์ฉ`));
|
|
3126
|
+
log(dim(` โ .harness/MIGRATED_TO_LEERNESS.md ์๋ด ์ถ๊ฐ๋จ (backward compat ๋ณด์กด)`));
|
|
3127
|
+
} else if (dryRun) {
|
|
3128
|
+
log(yel(` (dry-run โ ์ค์ ๋ณ๊ฒฝ ์์. ์คํ: leerness migrate-workspace-dir)`));
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
|
|
2878
3132
|
// 1.9.199: wakeup miss ์๋ ํ๋ณต ๊ฐํ โ last-handoff timestamp ๊ธฐ๋ก + 25min ๊ธฐ๋ interval ์ ๋ฐ ์ธก์
|
|
2879
3133
|
// ์ฌ์ฉ์ ๋ช
์ (1.9.198 ํ์): "22:01์ ๋ผ์ด๋์ ์๋์ง์
๋์ง์์์ด"
|
|
2880
3134
|
// 1.9.196 task-log mtime ๊ธฐ๋ฐ detector ๋ task-log ๊ฐ ์์ฃผ ์ ์
๋ฐ์ดํธ๋๋ฉด false positive.
|
|
@@ -16280,6 +16534,10 @@ async function main() {
|
|
|
16280
16534
|
if (cmd === 'pre-wake-audit') return preWakeAuditCmd(arg('--path', process.cwd()), args[1]);
|
|
16281
16535
|
// 1.9.210: leerness wakeup-interval <get|set|auto|history|record> โ adaptive interval (์ฌ์ฉ์ ๋ช
์)
|
|
16282
16536
|
if (cmd === 'wakeup-interval') return wakeupIntervalCmd(arg('--path', process.cwd()), args[1], args[2]);
|
|
16537
|
+
// 1.9.211: leerness workspace-dir <get|guide> โ ํ์ฌ ์ํฌ์คํ์ด์ค ๋๋ ํ ๋ฆฌ / AI ์ฐธ์กฐ ๊ฐ์ด๋ (์ฌ์ฉ์ ๋ช
์)
|
|
16538
|
+
if (cmd === 'workspace-dir') return workspaceDirCmd(arg('--path', process.cwd()), args[1]);
|
|
16539
|
+
// 1.9.211: leerness migrate-workspace-dir โ .harness โ .leerness ๋ง์ด๊ทธ๋ ์ด์
(์ฌ์ฉ์ ๋ช
์)
|
|
16540
|
+
if (cmd === 'migrate-workspace-dir') return migrateWorkspaceDirCmd(arg('--path', process.cwd()));
|
|
16283
16541
|
if (cmd === 'rule' && args[1] === 'add') return ruleAdd(arg('--path', process.cwd()), args.slice(2).filter(x => !x.startsWith('-')).join(' '));
|
|
16284
16542
|
if (cmd === 'rule' && args[1] === 'list') return ruleList(arg('--path', process.cwd()));
|
|
16285
16543
|
if (cmd === 'rule' && args[1] === 'remove') return ruleRemove(arg('--path', process.cwd()), args[2]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.211",
|
|
4
4
|
"description": "Leerness: ๋นํ๊ดด ๋ง์ด๊ทธ๋ ์ด์
, ์๋ ๋ฒ์ ๊ฐ์งยท์
๋ฐ์ดํธ, ๊ณํ/์งํ/ํธ๋์คํ ์๋ํ, ๊ฒ์ผ๋ฆยท์ํฌ๋ฆฟยท์ธ์ฝ๋ฉ ์๋ ๊ฐ๋, Claude Code ์ฌ๋์ ํตํฉ์ ๊ฐ์ถ ํ๊ตญ์ด ์ฐ์ AI ๊ฐ๋ฐ ํ๋ค์ค.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|