@neikyun/ciel 5.2.6 → 5.2.8
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/ciel.js +124 -2
- package/package.json +1 -1
- package/scripts/postinstall.cjs +49 -11
package/bin/ciel.js
CHANGED
|
@@ -1,6 +1,128 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Ciel CLI — bootstrap entry point
|
|
3
|
-
//
|
|
4
|
-
//
|
|
3
|
+
// Vérifie si l'initialisation est nécessaire, sinon lance la CLI normalement.
|
|
4
|
+
// Solution de secours quand le postinstall npm ne s'exécute pas.
|
|
5
5
|
|
|
6
|
+
const { existsSync, mkdirSync, writeFileSync, readFileSync, copyFileSync, readdirSync, chmodSync, unlinkSync } = require("fs");
|
|
7
|
+
const { join, dirname } = require("path");
|
|
8
|
+
const { execSync } = require("child_process");
|
|
9
|
+
|
|
10
|
+
const PKG_DIR = join(__dirname, "..");
|
|
11
|
+
const PKG = JSON.parse(readFileSync(join(PKG_DIR, "package.json"), "utf-8"));
|
|
12
|
+
const CIEL_VERSION = PKG.version || "0.0.0";
|
|
13
|
+
const ASSETS = join(PKG_DIR, "assets");
|
|
14
|
+
|
|
15
|
+
// Vérifier si une initialisation est nécessaire
|
|
16
|
+
const targetDir = process.env.INIT_CWD || process.cwd();
|
|
17
|
+
const memPath = join(targetDir, ".ciel", "memory.json");
|
|
18
|
+
const needsInit = !existsSync(memPath);
|
|
19
|
+
|
|
20
|
+
function copyDir(src, dest) {
|
|
21
|
+
if (!existsSync(src)) return 0;
|
|
22
|
+
let count = 0;
|
|
23
|
+
mkdirSync(dest, { recursive: true });
|
|
24
|
+
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
25
|
+
const s = join(src, entry.name), d = join(dest, entry.name);
|
|
26
|
+
if (entry.isDirectory()) count += copyDir(s, d);
|
|
27
|
+
else { copyFileSync(s, d); if (s.endsWith(".sh")) try { chmodSync(d, 0o755); } catch {} count++; }
|
|
28
|
+
}
|
|
29
|
+
return count;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function patchConfig(targetDir, assets) {
|
|
33
|
+
const cfgPath = join(targetDir, "opencode.json");
|
|
34
|
+
if (!existsSync(cfgPath)) return false;
|
|
35
|
+
try {
|
|
36
|
+
const cfg = JSON.parse(readFileSync(cfgPath, "utf-8"));
|
|
37
|
+
if (!cfg.plugin) cfg.plugin = [];
|
|
38
|
+
cfg.plugin = cfg.plugin.filter(p => p !== "./.opencode/plugins/ciel.ts");
|
|
39
|
+
if (!cfg.plugin.includes("@neikyun/ciel")) cfg.plugin.push("@neikyun/ciel");
|
|
40
|
+
if (!cfg.instructions) cfg.instructions = [];
|
|
41
|
+
if (!cfg.instructions.includes("AGENTS.md")) cfg.instructions.push("AGENTS.md");
|
|
42
|
+
writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
|
|
43
|
+
return true;
|
|
44
|
+
} catch { return false; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function runInit(targetDir, assets) {
|
|
48
|
+
let total = 0;
|
|
49
|
+
|
|
50
|
+
// .ciel/ state
|
|
51
|
+
mkdirSync(join(targetDir, ".ciel"), { recursive: true });
|
|
52
|
+
if (!existsSync(join(targetDir, ".ciel/map.json")))
|
|
53
|
+
writeFileSync(join(targetDir, ".ciel/map.json"), JSON.stringify({ modules: [], lastUpdated: "" }), "utf-8");
|
|
54
|
+
if (!existsSync(join(targetDir, ".ciel/parking.md")))
|
|
55
|
+
writeFileSync(join(targetDir, ".ciel/parking.md"), "# Ciel Parking Lot\n\n", "utf-8");
|
|
56
|
+
|
|
57
|
+
// OpenCode files
|
|
58
|
+
if (existsSync(join(targetDir, "opencode.json")) || existsSync(join(targetDir, ".opencode"))) {
|
|
59
|
+
// Clean old curl plugin
|
|
60
|
+
const old = join(targetDir, ".opencode/plugins/ciel.ts");
|
|
61
|
+
if (existsSync(old)) { try { unlinkSync(old); } catch {} }
|
|
62
|
+
// Copy agents
|
|
63
|
+
total += copyDir(join(assets, "platforms/opencode/.opencode/agents"), join(targetDir, ".opencode/agents"));
|
|
64
|
+
// Copy commands
|
|
65
|
+
total += copyDir(join(assets, "platforms/opencode/.opencode/commands"), join(targetDir, ".opencode/commands"));
|
|
66
|
+
// Copy AGENTS.md
|
|
67
|
+
if (existsSync(join(assets, "platforms/opencode/AGENTS.md"))) {
|
|
68
|
+
copyFileSync(join(assets, "platforms/opencode/AGENTS.md"), join(targetDir, "AGENTS.md"));
|
|
69
|
+
total++;
|
|
70
|
+
}
|
|
71
|
+
if (patchConfig(targetDir, assets)) total++;
|
|
72
|
+
console.error(` ${green("✓")} OpenCode: ${total} fichiers`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Claude Code files
|
|
76
|
+
if (existsSync(join(targetDir, ".claude/settings.json")) || existsSync(join(targetDir, ".claude"))) {
|
|
77
|
+
total += copyDir(join(assets, ".claude/agents"), join(targetDir, ".claude/agents"));
|
|
78
|
+
total += copyDir(join(assets, ".claude/hooks"), join(targetDir, ".claude/hooks"));
|
|
79
|
+
total += copyDir(join(assets, "commands"), join(targetDir, ".claude/commands"));
|
|
80
|
+
if (existsSync(join(assets, ".claude/settings.json"))) {
|
|
81
|
+
copyFileSync(join(assets, ".claude/settings.json"), join(targetDir, ".claude/settings.json"));
|
|
82
|
+
}
|
|
83
|
+
if (existsSync(join(assets, "CLAUDE.md"))) {
|
|
84
|
+
copyFileSync(join(assets, "CLAUDE.md"), join(targetDir, "CLAUDE.md"));
|
|
85
|
+
}
|
|
86
|
+
console.error(` ${green("✓")} Claude Code: ${total} fichiers`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Save version
|
|
90
|
+
writeFileSync(memPath, JSON.stringify({ cielVersion: CIEL_VERSION, lastUpdated: new Date().toISOString() }, null, 2), "utf-8");
|
|
91
|
+
return total;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const c = (code, s) => process.stderr.isTTY ? `\x1b[${code}m${s}\x1b[0m` : s;
|
|
95
|
+
const green = (s) => c(32, s);
|
|
96
|
+
const cyan = (s) => c(36, s);
|
|
97
|
+
|
|
98
|
+
if (needsInit) {
|
|
99
|
+
const args = process.argv.slice(2);
|
|
100
|
+
if (!args.includes("--help") && !args.includes("-h") && !args.includes("--version") && !args.includes("-v")) {
|
|
101
|
+
try {
|
|
102
|
+
const hasOC = existsSync(join(targetDir, "opencode.json")) || existsSync(join(targetDir, ".opencode"));
|
|
103
|
+
const hasClaude = existsSync(join(targetDir, ".claude/settings.json")) || existsSync(join(targetDir, ".claude"));
|
|
104
|
+
const hasOC_CLI = (() => { try { return execSync("opencode --version 2>&1", { stdio: "pipe", timeout: 3000 }).toString().length > 0; } catch { return false; } })();
|
|
105
|
+
const hasClaude_CLI = (() => { try { return execSync("claude --version 2>&1", { stdio: "pipe", timeout: 3000 }).toString().length > 0; } catch { return false; } })();
|
|
106
|
+
|
|
107
|
+
// Créer les configs si CLI détectée mais pas de fichier
|
|
108
|
+
if (hasOC_CLI && !hasOC) {
|
|
109
|
+
writeFileSync(join(targetDir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", plugin: ["@neikyun/ciel"] }, null, 2) + "\n", "utf-8");
|
|
110
|
+
}
|
|
111
|
+
if (hasClaude_CLI && !hasClaude) {
|
|
112
|
+
mkdirSync(join(targetDir, ".claude"), { recursive: true });
|
|
113
|
+
writeFileSync(join(targetDir, ".claude/settings.json"), "{}\n", "utf-8");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (hasOC || hasClaude || hasOC_CLI || hasClaude_CLI) {
|
|
117
|
+
if (existsSync(ASSETS) && existsSync(join(ASSETS, "platforms/opencode/.opencode/agents/ciel.md"))) {
|
|
118
|
+
console.error(`\n ⚡ Ciel v${CIEL_VERSION} — Premier lancement, initialisation...`);
|
|
119
|
+
const n = runInit(targetDir, ASSETS);
|
|
120
|
+
console.error(` ${green("✓")} Ciel v${CIEL_VERSION} configuré (${n} fichiers)\n`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch {}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Lancer la CLI normalement
|
|
6
128
|
require("../dist/cli/index.js");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neikyun/ciel",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.8",
|
|
4
4
|
"description": "Ciel — Deep-reasoning pipeline for LLM-assisted development. OpenCode plugin + multi-platform CLI (OpenCode, Claude Code, more).",
|
|
5
5
|
"main": "./dist/plugin/index.js",
|
|
6
6
|
"types": "./dist/plugin/index.d.ts",
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -33,6 +33,14 @@ function resolveAssets() {
|
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
function detectCLI(name) {
|
|
37
|
+
try {
|
|
38
|
+
const { execSync } = require("child_process");
|
|
39
|
+
const r = execSync(name + " --version 2>&1", { stdio: "pipe", timeout: 3000, encoding: "utf8" });
|
|
40
|
+
return r.length > 0 && !r.includes("not found");
|
|
41
|
+
} catch { return false; }
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
// ---- Installation ----
|
|
37
45
|
function copyDir(src, dest) {
|
|
38
46
|
if (!existsSync(src)) return 0;
|
|
@@ -109,25 +117,55 @@ async function main() {
|
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
if (platforms.length === 0) {
|
|
112
|
-
// Aucune plateforme détectée →
|
|
113
|
-
|
|
120
|
+
// Aucune plateforme détectée → chercher les CLIs installées
|
|
121
|
+
const hasOpenCode = detectCLI("opencode");
|
|
122
|
+
const hasClaude = detectCLI("claude");
|
|
123
|
+
|
|
124
|
+
if (!hasOpenCode && !hasClaude) {
|
|
125
|
+
console.error(` ${yellow("~")} Aucune plateforme détectée.`);
|
|
126
|
+
console.error(` Installez ${cyan("opencode")} ou ${cyan("claude")} puis relancez.`);
|
|
127
|
+
console.error(` Ou: ${green("npx ciel init")}\n`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Proposer de configurer les CLIs détectées
|
|
132
|
+
let creer = !process.stdin.isTTY;
|
|
114
133
|
if (process.stdin.isTTY) {
|
|
134
|
+
const detected = [hasOpenCode && "OpenCode", hasClaude && "Claude Code"].filter(Boolean).join(" + ");
|
|
115
135
|
try {
|
|
116
136
|
const readline = require("readline");
|
|
117
137
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
118
|
-
creer = await new Promise(r => rl.question(` ${yellow("?")} Configurer Ciel pour
|
|
138
|
+
creer = await new Promise(r => rl.question(` ${yellow("?")} Configurer Ciel pour ${cyan(detected)} ? ${green("(Y/n)")} `, a => { rl.close(); r(a.trim().toLowerCase() !== "n"); }));
|
|
119
139
|
} catch { creer = true; }
|
|
120
140
|
}
|
|
121
|
-
|
|
122
|
-
|
|
141
|
+
|
|
142
|
+
if (!creer) {
|
|
143
|
+
console.error(` ${cyan("→")} Annulé. Utilisez ${green("npx ciel init")} plus tard.\n`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Configurer les plateformes détectées
|
|
148
|
+
if (hasOpenCode) {
|
|
123
149
|
const cfgPath = join(targetDir, "opencode.json");
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
150
|
+
if (!existsSync(cfgPath)) {
|
|
151
|
+
const cfg = { $schema: "https://opencode.ai/config.json", plugin: ["@neikyun/ciel"] };
|
|
152
|
+
writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
|
|
153
|
+
console.error(` ${green("✓")} opencode.json créé`);
|
|
154
|
+
}
|
|
127
155
|
platforms.push("OpenCode");
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (hasClaude) {
|
|
159
|
+
const claudeDir = join(targetDir, ".claude");
|
|
160
|
+
if (!existsSync(claudeDir)) {
|
|
161
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
162
|
+
}
|
|
163
|
+
const settingsPath = join(claudeDir, "settings.json");
|
|
164
|
+
if (!existsSync(settingsPath)) {
|
|
165
|
+
writeFileSync(settingsPath, JSON.stringify({}, null, 2) + "\n", "utf-8");
|
|
166
|
+
console.error(` ${green("✓")} .claude/settings.json créé`);
|
|
167
|
+
}
|
|
168
|
+
platforms.push("Claude Code");
|
|
131
169
|
}
|
|
132
170
|
}
|
|
133
171
|
|