@thanhthi2895/luna-ai 2.16.2 → 2.16.4
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 +22 -6
- package/bin/commands/add-skill.js +1 -1
- package/bin/commands/install.js +43 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,13 +4,29 @@ Agentic Workflow Framework for the **Vibe Coding** era, with an integrated **Dyn
|
|
|
4
4
|
|
|
5
5
|
## 🚀 Quick Start
|
|
6
6
|
|
|
7
|
+
### Global Installation (Recommended)
|
|
8
|
+
Installs the framework globally, available for all your projects.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# 1. Install the framework globally into ~/.claude
|
|
12
|
+
npx @thanhthi2895/luna-ai -g
|
|
13
|
+
|
|
14
|
+
# 2. Initialize global metadata (first time only)
|
|
15
|
+
luna init -g
|
|
16
|
+
|
|
17
|
+
# 3. Open Claude Code in any project and start Vibe Coding!
|
|
18
|
+
claude
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Local Project Installation
|
|
22
|
+
Installs the framework directly into the current project's directory.
|
|
23
|
+
|
|
7
24
|
```bash
|
|
8
|
-
# 1. Install the framework
|
|
9
|
-
npx @thanhthi2895/luna-ai
|
|
10
|
-
npx @thanhthi2895/luna-ai -g # global
|
|
25
|
+
# 1. Install the framework locally
|
|
26
|
+
npx @thanhthi2895/luna-ai
|
|
11
27
|
|
|
12
|
-
# 2. Initialize project
|
|
13
|
-
luna
|
|
28
|
+
# 2. Initialize project structure and memory
|
|
29
|
+
luna init
|
|
14
30
|
|
|
15
31
|
# 3. Open Claude Code and start Vibe Coding!
|
|
16
32
|
claude
|
|
@@ -21,7 +37,7 @@ claude
|
|
|
21
37
|
## 🎯 Goal: Vibe Coding - Full Auto
|
|
22
38
|
Users simply provide an idea. The system automatically coordinates a team of specialized Agents to assess risk, create multi-level plans, execute with TDD standards, and deliver the product at optimal speed.
|
|
23
39
|
|
|
24
|
-
## 🚀 Breakthrough Features (V2.
|
|
40
|
+
## 🚀 Breakthrough Features (V2.16)
|
|
25
41
|
- **Layered Cache**: Multi-level memory cache (L1/L2/L3) for large projects (20+ modules, 200+ files).
|
|
26
42
|
- **Semantic Code Graph**: Uses `lu:gkg` (GitLab Knowledge Graph) to see all project connections and run impact analysis.
|
|
27
43
|
- **Context Distilling**: Automatically filters out code noise, helping AI think faster and save tokens.
|
|
@@ -9,7 +9,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
9
9
|
const CWD = process.cwd();
|
|
10
10
|
/** Template optional skills located in package, not copied to project when running "luna" */
|
|
11
11
|
const PACKAGE_ROOT = path.join(__dirname, '..', '..');
|
|
12
|
-
const PACKAGE_SKILLS_OPTIONAL = path.join(PACKAGE_ROOT, '.agents', 'skills-optional');
|
|
12
|
+
const PACKAGE_SKILLS_OPTIONAL = path.join(PACKAGE_ROOT, 'agentic', 'antigravity', '.agents', 'skills-optional');
|
|
13
13
|
const SKILLS_DIR = path.join(CWD, '.agents', 'skills');
|
|
14
14
|
const REGISTRY_FILE = path.join(CWD, '.agents', 'skills-registry.json');
|
|
15
15
|
|
package/bin/commands/install.js
CHANGED
|
@@ -439,6 +439,27 @@ async function copyClaude_global(rootDir, claudeHome) {
|
|
|
439
439
|
throw new Error(`Canonical Claude directory missing: ${srcClaude}`);
|
|
440
440
|
}
|
|
441
441
|
const destClaude = claudeHome;
|
|
442
|
+
|
|
443
|
+
// PREVENT fs-extra "Source and destination must not be the same" error
|
|
444
|
+
// If destClaude contains symlinks pointing to srcClaude elements, fs.copy will crash.
|
|
445
|
+
// We remove those specific symlinks before copying.
|
|
446
|
+
try {
|
|
447
|
+
const srcItems = await fs.readdir(srcClaude);
|
|
448
|
+
for (const item of srcItems) {
|
|
449
|
+
const destPath = path.join(destClaude, item);
|
|
450
|
+
try {
|
|
451
|
+
const tgtStat = await fs.lstat(destPath);
|
|
452
|
+
if (tgtStat.isSymbolicLink()) {
|
|
453
|
+
await fs.remove(destPath);
|
|
454
|
+
}
|
|
455
|
+
} catch (e) {
|
|
456
|
+
// Ignore if doesn't exist
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
} catch (err) {
|
|
460
|
+
console.error(` Warning: Could not run symlink cleanup in ${destClaude}:`, err.message);
|
|
461
|
+
}
|
|
462
|
+
|
|
442
463
|
const skipPaths = [
|
|
443
464
|
path.join(srcClaude, 'ai-cache'),
|
|
444
465
|
path.join(srcClaude, 'hook-state'), // Runtime data, don't copy
|
|
@@ -687,23 +708,30 @@ export async function installGlobal(rootDir) {
|
|
|
687
708
|
// Write settings.json with absolute paths for global hooks (replace $CLAUDE_PROJECT_DIR → absolute)
|
|
688
709
|
await writeGlobalSettingsJson(rootDir, claudeHome);
|
|
689
710
|
|
|
690
|
-
// Copy statusline.cjs and its lib/ dependency from .
|
|
691
|
-
const
|
|
711
|
+
// Copy statusline.cjs and its lib/ dependency from canonical .claude/ to ~/.claude/
|
|
712
|
+
const canonicalClaude = getCanonicalClaudeDir(rootDir);
|
|
713
|
+
const statuslineSrc = path.join(canonicalClaude, 'statusline.cjs');
|
|
714
|
+
const statuslineDest = path.join(claudeHome, 'statusline.cjs');
|
|
715
|
+
const libDest = path.join(claudeHome, 'lib');
|
|
692
716
|
if (await fs.pathExists(statuslineSrc)) {
|
|
693
|
-
await fs.
|
|
717
|
+
try { await fs.remove(statuslineDest); } catch(e){}
|
|
718
|
+
await fs.copy(statuslineSrc, statuslineDest, { overwrite: true });
|
|
694
719
|
// statusline.cjs requires ./lib/ — copy lib/ to ~/.claude/lib/
|
|
695
|
-
const libSrc = path.join(
|
|
720
|
+
const libSrc = path.join(canonicalClaude, 'lib');
|
|
696
721
|
if (await fs.pathExists(libSrc)) {
|
|
697
|
-
await fs.
|
|
722
|
+
try { await fs.remove(libDest); } catch(e){}
|
|
723
|
+
await fs.copy(libSrc, libDest, { overwrite: true });
|
|
698
724
|
}
|
|
699
725
|
console.log(` Copied statusline.cjs + lib/ → ~/.claude/`);
|
|
700
726
|
}
|
|
701
727
|
|
|
702
728
|
// Copy canonical .luna.json to ~/.claude/.luna.json
|
|
703
729
|
const lunaJsonSrc = path.join(rootDir, 'agentic', 'claude', '.luna.json');
|
|
730
|
+
const lunaJsonDest = path.join(claudeHome, '.luna.json');
|
|
704
731
|
|
|
705
732
|
if (await fs.pathExists(lunaJsonSrc)) {
|
|
706
|
-
await fs.
|
|
733
|
+
try { await fs.remove(lunaJsonDest); } catch(e){}
|
|
734
|
+
await fs.copy(lunaJsonSrc, lunaJsonDest, { overwrite: true });
|
|
707
735
|
console.log(` Copied .luna.json → ~/.claude/.luna.json`);
|
|
708
736
|
} else {
|
|
709
737
|
console.log(' Warning: canonical agentic/claude/.luna.json missing. Skip publishing ~/.claude/.luna.json');
|
|
@@ -713,12 +741,16 @@ export async function installGlobal(rootDir) {
|
|
|
713
741
|
await ensureLunaCli(claudeHome);
|
|
714
742
|
|
|
715
743
|
// Copy CLAUDE.md into ~/.claude/ (Claude Code reads global instructions from here)
|
|
716
|
-
|
|
744
|
+
const claudeMdDest = path.join(claudeHome, 'CLAUDE.md');
|
|
745
|
+
try { await fs.remove(claudeMdDest); } catch(e){}
|
|
746
|
+
await fs.copy(getCanonicalClaudeMd(rootDir), claudeMdDest, { overwrite: true });
|
|
717
747
|
await ensureGeminiSymlink(claudeHome);
|
|
718
748
|
}
|
|
719
749
|
|
|
720
750
|
// Copy CLAUDE.md + GEMINI.md symlink into ~/.luna-ai/ (as reference)
|
|
721
|
-
|
|
751
|
+
const lunaAiClaudeMdDest = path.join(lunaHome, 'CLAUDE.md');
|
|
752
|
+
try { await fs.remove(lunaAiClaudeMdDest); } catch(e){}
|
|
753
|
+
await fs.copy(getCanonicalClaudeMd(rootDir), lunaAiClaudeMdDest, { overwrite: true });
|
|
722
754
|
await ensureGeminiSymlink(lunaHome);
|
|
723
755
|
|
|
724
756
|
// Create plans/archive directory at ~/.luna-ai/
|
|
@@ -818,14 +850,15 @@ async function ensureLunaCli(claudeHome) {
|
|
|
818
850
|
|
|
819
851
|
/**
|
|
820
852
|
* Write settings.json into ~/.claude/ for global install.
|
|
821
|
-
* Reads from
|
|
853
|
+
* Reads from canonical agentic/claude/.claude/settings.json and overwrites ~/.claude/settings.json.
|
|
822
854
|
*/
|
|
823
855
|
async function writeGlobalSettingsJson(rootDir, claudeHome) {
|
|
824
|
-
const srcPath = path.join(rootDir, '
|
|
856
|
+
const srcPath = path.join(getCanonicalClaudeDir(rootDir), 'settings.json');
|
|
825
857
|
const destPath = path.join(claudeHome, 'settings.json');
|
|
826
858
|
|
|
827
859
|
if (!await fs.pathExists(srcPath)) return;
|
|
828
860
|
|
|
861
|
+
try { await fs.remove(destPath); } catch (e) {}
|
|
829
862
|
await fs.copy(srcPath, destPath, { overwrite: true });
|
|
830
863
|
console.log(` Copied .agents/settings.json → ~/.claude/settings.json`);
|
|
831
864
|
}
|