@haposoft/cafekit 0.10.2 → 0.10.3
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/lib/skill-deps.js +13 -2
- package/bin/phases/post-install.js +9 -38
- package/package.json +1 -1
package/bin/lib/skill-deps.js
CHANGED
|
@@ -81,9 +81,20 @@ function npmInstall(dir) {
|
|
|
81
81
|
return run('npm', ['install', '--no-audit', '--no-fund'], { cwd: dir }).ok;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Download the Puppeteer Chromium browser for chrome-devtools.
|
|
86
|
+
* Prefer puppeteer's own install script (cache-aware, same as its postinstall);
|
|
87
|
+
* fall back to the bundled @puppeteer/browsers CLI. `npx puppeteer ...` is
|
|
88
|
+
* avoided — puppeteer ships no `puppeteer` bin under that invocation and `--yes`
|
|
89
|
+
* would refetch from the registry.
|
|
90
|
+
*/
|
|
85
91
|
function installChromium(scriptsDir) {
|
|
86
|
-
|
|
92
|
+
// Absolute path so it resolves regardless of the child process cwd.
|
|
93
|
+
const installMjs = path.resolve(scriptsDir, 'node_modules', 'puppeteer', 'install.mjs');
|
|
94
|
+
if (fs.existsSync(installMjs)) {
|
|
95
|
+
return run('node', [installMjs], { cwd: scriptsDir }).ok;
|
|
96
|
+
}
|
|
97
|
+
return run('npx', ['--yes', '@puppeteer/browsers', 'install', 'chrome'], { cwd: scriptsDir }).ok;
|
|
87
98
|
}
|
|
88
99
|
|
|
89
100
|
/** Does a skill scripts dir declare a given npm dependency? */
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Phase: post-install runtime configuration.
|
|
3
3
|
*
|
|
4
|
-
* OpenCode model
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* opencode.json) happen only when a value is actually provided.
|
|
4
|
+
* OpenCode model + addressing config. Interactive prompts use ctx.ui (clack);
|
|
5
|
+
* in non-interactive/dry-run they are skipped via fallbacks so spawned/CI runs
|
|
6
|
+
* never hang.
|
|
8
7
|
*
|
|
9
|
-
* Note: CafeKit no longer
|
|
10
|
-
* removed
|
|
11
|
-
*
|
|
8
|
+
* Note: CafeKit no longer prompts for a Gemini API key. The upstream gemini-cli
|
|
9
|
+
* was removed, and the key now serves only the ai-multimodal skill — which
|
|
10
|
+
* documents it in its own `.env.example`. Users set GEMINI_API_KEY there when
|
|
11
|
+
* (and only if) they use that skill.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
|
-
const { PLATFORMS } = require('../lib/context');
|
|
17
16
|
const { setupOpenCodeModel } = require('../lib/opencode-install');
|
|
18
17
|
|
|
19
18
|
/** Human assistant name for the active platform(s). */
|
|
@@ -21,33 +20,6 @@ function assistantName(ctx) {
|
|
|
21
20
|
return ctx.platforms.includes('claude') ? 'Claude Code' : 'OpenCode';
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
function configureGeminiKey(ctx, apiKey, platforms) {
|
|
25
|
-
const envBody = `GEMINI_API_KEY=${apiKey}\nVISUAL_MODEL=gemma-4-31b-it\nSEARCH_MODEL=gemini-2.5-pro\n`;
|
|
26
|
-
const targets = platforms.filter((key) => PLATFORMS[key]).map((key) => PLATFORMS[key].folder);
|
|
27
|
-
if (targets.length === 0) targets.push('.claude');
|
|
28
|
-
|
|
29
|
-
for (const folder of targets) {
|
|
30
|
-
try {
|
|
31
|
-
const targetDir = path.join(process.cwd(), folder);
|
|
32
|
-
if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
|
|
33
|
-
fs.writeFileSync(path.join(targetDir, '.env'), envBody, { mode: 0o600 });
|
|
34
|
-
ctx.ui.success(`Gemini API key stored in ${folder}/.env (0600)`);
|
|
35
|
-
} catch (error) {
|
|
36
|
-
ctx.ui.error(`Failed to configure Gemini API key: ${error.message}`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function setupGeminiKey(ctx) {
|
|
42
|
-
const apiKey = await ctx.ui.text(
|
|
43
|
-
{ message: 'Gemini API key for AI skills (Enter to skip)', placeholder: 'aistudio.google.com/apikey' },
|
|
44
|
-
''
|
|
45
|
-
);
|
|
46
|
-
if (apiKey && typeof apiKey === 'string' && apiKey.trim()) {
|
|
47
|
-
configureGeminiKey(ctx, apiKey.trim(), ctx.platforms);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
23
|
function configureAddressing(ctx, userAddress) {
|
|
52
24
|
const claudeMdFile = path.join(process.cwd(), 'CLAUDE.md');
|
|
53
25
|
if (!fs.existsSync(claudeMdFile)) {
|
|
@@ -92,7 +64,7 @@ async function setupAddressing(ctx) {
|
|
|
92
64
|
/** Run the post-install configuration sequence. */
|
|
93
65
|
async function runPostInstall(ctx) {
|
|
94
66
|
if (ctx.dryRun) {
|
|
95
|
-
ctx.ui.info('[dry-run] Skipping OpenCode model /
|
|
67
|
+
ctx.ui.info('[dry-run] Skipping OpenCode model / addressing setup');
|
|
96
68
|
return ctx;
|
|
97
69
|
}
|
|
98
70
|
|
|
@@ -103,7 +75,6 @@ async function runPostInstall(ctx) {
|
|
|
103
75
|
await setupOpenCodeModel(ctx.platforms, ctx.results);
|
|
104
76
|
}
|
|
105
77
|
|
|
106
|
-
await setupGeminiKey(ctx);
|
|
107
78
|
await setupAddressing(ctx);
|
|
108
79
|
|
|
109
80
|
// Re-record CLAUDE.md baseline so the installer-managed file (template +
|
|
@@ -115,4 +86,4 @@ async function runPostInstall(ctx) {
|
|
|
115
86
|
return ctx;
|
|
116
87
|
}
|
|
117
88
|
|
|
118
|
-
module.exports = {
|
|
89
|
+
module.exports = { configureAddressing, runPostInstall };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "Claude Code-first spec-driven workflow for AI coding assistants. Bundles CafeKit hapo: skills, runtime hooks, agents, and installer scaffolding.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|