@neikyun/ciel 5.2.8 → 5.2.10

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.
Files changed (2) hide show
  1. package/bin/ciel.js +88 -69
  2. package/package.json +1 -1
package/bin/ciel.js CHANGED
@@ -1,22 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  // Ciel CLI — bootstrap entry point
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.
3
+ // Vérifie si l'initialisation est nécessaire et détecte les nouvelles plateformes.
5
4
 
6
5
  const { existsSync, mkdirSync, writeFileSync, readFileSync, copyFileSync, readdirSync, chmodSync, unlinkSync } = require("fs");
7
- const { join, dirname } = require("path");
6
+ const { join } = require("path");
8
7
  const { execSync } = require("child_process");
9
8
 
10
9
  const PKG_DIR = join(__dirname, "..");
11
10
  const PKG = JSON.parse(readFileSync(join(PKG_DIR, "package.json"), "utf-8"));
12
11
  const CIEL_VERSION = PKG.version || "0.0.0";
13
12
  const ASSETS = join(PKG_DIR, "assets");
14
-
15
- // Vérifier si une initialisation est nécessaire
16
13
  const targetDir = process.env.INIT_CWD || process.cwd();
17
14
  const memPath = join(targetDir, ".ciel", "memory.json");
18
- const needsInit = !existsSync(memPath);
19
15
 
16
+ const c = (code, s) => process.stderr.isTTY ? `\x1b[${code}m${s}\x1b[0m` : s;
17
+ const green = (s) => c(32, s);
18
+ const cyan = (s) => c(36, s);
19
+
20
+ // ---- Helpers ----
20
21
  function copyDir(src, dest) {
21
22
  if (!existsSync(src)) return 0;
22
23
  let count = 0;
@@ -29,7 +30,7 @@ function copyDir(src, dest) {
29
30
  return count;
30
31
  }
31
32
 
32
- function patchConfig(targetDir, assets) {
33
+ function patchOpencodeJson(targetDir) {
33
34
  const cfgPath = join(targetDir, "opencode.json");
34
35
  if (!existsSync(cfgPath)) return false;
35
36
  try {
@@ -44,84 +45,102 @@ function patchConfig(targetDir, assets) {
44
45
  } catch { return false; }
45
46
  }
46
47
 
47
- function runInit(targetDir, assets) {
48
+ // ---- Détection des plateformes ----
49
+ function detectPlatforms() {
50
+ const platforms = [];
51
+ const hasOC = existsSync(join(targetDir, "opencode.json")) || existsSync(join(targetDir, ".opencode"));
52
+ const hasClaude = existsSync(join(targetDir, ".claude/settings.json")) || existsSync(join(targetDir, ".claude"));
53
+
54
+ // Détection CLI
55
+ const hasOC_CLI = (() => { try { const r = execSync("opencode --version 2>&1", { stdio: "pipe", timeout: 5000 }); return r.toString().length > 0; } catch { return false; } })();
56
+ const hasClaude_CLI = (() => { try { const r = execSync("claude --version 2>&1", { stdio: "pipe", timeout: 5000 }); return r.toString().length > 0; } catch { return false; } })();
57
+
58
+ if (hasOC || hasOC_CLI) platforms.push("OpenCode");
59
+ if (hasClaude || hasClaude_CLI) platforms.push("Claude Code");
60
+ return platforms;
61
+ }
62
+
63
+ // ---- Installer une plateforme ----
64
+ function installOpenCode() {
48
65
  let total = 0;
66
+ // Nettoyer ancien plugin curl
67
+ const old = join(targetDir, ".opencode/plugins/ciel.ts");
68
+ if (existsSync(old)) { try { unlinkSync(old); } catch {} }
69
+ total += copyDir(join(ASSETS, "platforms/opencode/.opencode/agents"), join(targetDir, ".opencode/agents"));
70
+ total += copyDir(join(ASSETS, "platforms/opencode/.opencode/commands"), join(targetDir, ".opencode/commands"));
71
+ if (existsSync(join(ASSETS, "platforms/opencode/AGENTS.md"))) {
72
+ copyFileSync(join(ASSETS, "platforms/opencode/AGENTS.md"), join(targetDir, "AGENTS.md"));
73
+ total++;
74
+ }
75
+ if (patchOpencodeJson(targetDir)) total++;
76
+ return total;
77
+ }
78
+
79
+ function installClaude() {
80
+ let total = 0;
81
+ total += copyDir(join(ASSETS, ".claude/agents"), join(targetDir, ".claude/agents"));
82
+ total += copyDir(join(ASSETS, ".claude/hooks"), join(targetDir, ".claude/hooks"));
83
+ total += copyDir(join(ASSETS, "commands"), join(targetDir, ".claude/commands"));
84
+ if (existsSync(join(ASSETS, ".claude/settings.json"))) {
85
+ copyFileSync(join(ASSETS, ".claude/settings.json"), join(targetDir, ".claude/settings.json"));
86
+ }
87
+ if (existsSync(join(ASSETS, "CLAUDE.md"))) {
88
+ copyFileSync(join(ASSETS, "CLAUDE.md"), join(targetDir, "CLAUDE.md"));
89
+ }
90
+ return total;
91
+ }
49
92
 
50
- // .ciel/ state
93
+ function ensureCielState() {
51
94
  mkdirSync(join(targetDir, ".ciel"), { recursive: true });
52
95
  if (!existsSync(join(targetDir, ".ciel/map.json")))
53
96
  writeFileSync(join(targetDir, ".ciel/map.json"), JSON.stringify({ modules: [], lastUpdated: "" }), "utf-8");
54
97
  if (!existsSync(join(targetDir, ".ciel/parking.md")))
55
98
  writeFileSync(join(targetDir, ".ciel/parking.md"), "# Ciel Parking Lot\n\n", "utf-8");
99
+ writeFileSync(memPath, JSON.stringify({ cielVersion: CIEL_VERSION, lastUpdated: new Date().toISOString() }, null, 2), "utf-8");
100
+ }
56
101
 
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
- }
102
+ // ===== MAIN BOOT =====
103
+ const args = process.argv.slice(2);
104
+ const isHelp = args.includes("--help") || args.includes("-h");
105
+ const isVersion = args.includes("--version") || args.includes("-v");
74
106
 
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"));
107
+ if (!isHelp && !isVersion && ASSETS && existsSync(join(ASSETS, "platforms/opencode/.opencode/agents/ciel.md"))) {
108
+ try {
109
+ const storedVersion = (() => { try { return JSON.parse(readFileSync(memPath, "utf-8")).cielVersion; } catch { return null; } })();
110
+ const needsInit = !storedVersion || storedVersion !== CIEL_VERSION;
111
+
112
+ // Toujours détecter les plateformes
113
+ const platforms = detectPlatforms();
114
+
115
+ // Créer les configs si CLI détectée mais pas de fichiers
116
+ if (platforms.includes("OpenCode") && !existsSync(join(targetDir, "opencode.json"))) {
117
+ writeFileSync(join(targetDir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json", plugin: ["@neikyun/ciel"] }, null, 2) + "\n", "utf-8");
82
118
  }
83
- if (existsSync(join(assets, "CLAUDE.md"))) {
84
- copyFileSync(join(assets, "CLAUDE.md"), join(targetDir, "CLAUDE.md"));
119
+ if (platforms.includes("Claude Code") && !existsSync(join(targetDir, ".claude/settings.json"))) {
120
+ mkdirSync(join(targetDir, ".claude"), { recursive: true });
121
+ writeFileSync(join(targetDir, ".claude/settings.json"), "{}\n", "utf-8");
85
122
  }
86
- console.error(` ${green("✓")} Claude Code: ${total} fichiers`);
87
- }
88
123
 
89
- // Save version
90
- writeFileSync(memPath, JSON.stringify({ cielVersion: CIEL_VERSION, lastUpdated: new Date().toISOString() }, null, 2), "utf-8");
91
- return total;
92
- }
124
+ // Vérifier ce qui manque pour chaque plateforme détectée
125
+ const opencodeFilesExist = existsSync(join(targetDir, ".opencode/agents/ciel.md"));
126
+ const claudeFilesExist = existsSync(join(targetDir, ".claude/hooks/check-test-first.sh"));
93
127
 
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);
128
+ if (needsInit || (platforms.includes("OpenCode") && !opencodeFilesExist) || (platforms.includes("Claude Code") && !claudeFilesExist)) {
129
+ let n = 0;
130
+ console.error(`\n ⚡ Ciel v${CIEL_VERSION} Configuration...`);
131
+ ensureCielState();
97
132
 
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");
133
+ if (platforms.includes("OpenCode") && (!opencodeFilesExist || needsInit)) {
134
+ n += installOpenCode();
135
+ console.error(` ${green("")} OpenCode: agents + commands`);
110
136
  }
111
- if (hasClaude_CLI && !hasClaude) {
112
- mkdirSync(join(targetDir, ".claude"), { recursive: true });
113
- writeFileSync(join(targetDir, ".claude/settings.json"), "{}\n", "utf-8");
137
+ if (platforms.includes("Claude Code") && (!claudeFilesExist || needsInit)) {
138
+ n += installClaude();
139
+ console.error(` ${green("")} Claude Code: agents + hooks + commands`);
114
140
  }
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
- }
141
+ console.error(` ${green("✓")} Ciel v${CIEL_VERSION} prêt !\n`);
142
+ }
143
+ } catch {}
125
144
  }
126
145
 
127
146
  // Lancer la CLI normalement
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neikyun/ciel",
3
- "version": "5.2.8",
3
+ "version": "5.2.10",
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",