coding-friend-cli 1.0.2 → 1.0.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/README.md +4 -1
- package/dist/index.js +3 -3
- package/dist/update-IH3G4SN5.js +202 -0
- package/package.json +1 -1
- package/dist/update-6PPVL2KJ.js +0 -166
package/README.md
CHANGED
|
@@ -24,7 +24,10 @@ cf mcp [path] # Setup MCP server for LLM integration
|
|
|
24
24
|
# [path] is optional, default is `docs/learn`
|
|
25
25
|
# This prints a JSON config snippet to add to your client's MCP
|
|
26
26
|
cf statusline # Setup coding-friend statusline
|
|
27
|
-
cf update # Update plugin +
|
|
27
|
+
cf update # Update plugin + CLI + statusline
|
|
28
|
+
cf update --cli # Update only the CLI (npm package)
|
|
29
|
+
cf update --plugin # Update only the Claude Code plugin
|
|
30
|
+
cf update --statusline # Update only the statusline
|
|
28
31
|
cf help # Show all commands
|
|
29
32
|
```
|
|
30
33
|
|
package/dist/index.js
CHANGED
|
@@ -27,8 +27,8 @@ program.command("statusline").description("Setup coding-friend statusline in Cla
|
|
|
27
27
|
const { statuslineCommand } = await import("./statusline-7D6YU5YM.js");
|
|
28
28
|
await statuslineCommand();
|
|
29
29
|
});
|
|
30
|
-
program.command("update").description("Update coding-friend plugin and
|
|
31
|
-
const { updateCommand } = await import("./update-
|
|
32
|
-
await updateCommand();
|
|
30
|
+
program.command("update").description("Update coding-friend plugin, CLI, and statusline").option("--cli", "Update only the CLI (npm package)").option("--plugin", "Update only the Claude Code plugin").option("--statusline", "Update only the statusline").action(async (opts) => {
|
|
31
|
+
const { updateCommand } = await import("./update-IH3G4SN5.js");
|
|
32
|
+
await updateCommand(opts);
|
|
33
33
|
});
|
|
34
34
|
program.parse();
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ensureShellCompletion
|
|
3
|
+
} from "./chunk-VHZQ6KEU.js";
|
|
4
|
+
import {
|
|
5
|
+
commandExists,
|
|
6
|
+
run,
|
|
7
|
+
sleepSync
|
|
8
|
+
} from "./chunk-UFGNO6CW.js";
|
|
9
|
+
import {
|
|
10
|
+
claudeSettingsPath,
|
|
11
|
+
installedPluginsPath,
|
|
12
|
+
pluginCachePath
|
|
13
|
+
} from "./chunk-AQXTNLQD.js";
|
|
14
|
+
import {
|
|
15
|
+
log
|
|
16
|
+
} from "./chunk-6DUFTBTO.js";
|
|
17
|
+
import {
|
|
18
|
+
readJson,
|
|
19
|
+
writeJson
|
|
20
|
+
} from "./chunk-IUTXHCP7.js";
|
|
21
|
+
|
|
22
|
+
// src/commands/update.ts
|
|
23
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
24
|
+
import { dirname, join } from "path";
|
|
25
|
+
import { fileURLToPath } from "url";
|
|
26
|
+
import chalk from "chalk";
|
|
27
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
function getCliVersion() {
|
|
29
|
+
const pkg = JSON.parse(
|
|
30
|
+
readFileSync(join(__dirname, "..", "package.json"), "utf-8")
|
|
31
|
+
);
|
|
32
|
+
return pkg.version;
|
|
33
|
+
}
|
|
34
|
+
function getLatestCliVersion() {
|
|
35
|
+
return run("npm", ["view", "coding-friend-cli", "version"]);
|
|
36
|
+
}
|
|
37
|
+
function getInstalledVersion() {
|
|
38
|
+
const data = readJson(installedPluginsPath());
|
|
39
|
+
if (!data) return null;
|
|
40
|
+
const plugins = data.plugins ?? data;
|
|
41
|
+
for (const [key, value] of Object.entries(plugins)) {
|
|
42
|
+
if (!key.includes("coding-friend")) continue;
|
|
43
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
44
|
+
const entry = value[0];
|
|
45
|
+
if (typeof entry.version === "string") return entry.version;
|
|
46
|
+
}
|
|
47
|
+
if (typeof value === "object" && value !== null && "version" in value) {
|
|
48
|
+
return value.version;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
function getLatestVersion() {
|
|
54
|
+
let tag = run("gh", [
|
|
55
|
+
"api",
|
|
56
|
+
"repos/dinhanhthi/coding-friend/releases/latest",
|
|
57
|
+
"--jq",
|
|
58
|
+
".tag_name"
|
|
59
|
+
]);
|
|
60
|
+
if (!tag) {
|
|
61
|
+
const json = run("curl", [
|
|
62
|
+
"-s",
|
|
63
|
+
"https://api.github.com/repos/dinhanhthi/coding-friend/releases/latest"
|
|
64
|
+
]);
|
|
65
|
+
if (json) {
|
|
66
|
+
try {
|
|
67
|
+
const data = JSON.parse(json);
|
|
68
|
+
tag = data.tag_name;
|
|
69
|
+
} catch {
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!tag) return null;
|
|
74
|
+
return tag.replace(/^v/, "");
|
|
75
|
+
}
|
|
76
|
+
function getStatuslineVersion() {
|
|
77
|
+
const settings = readJson(claudeSettingsPath());
|
|
78
|
+
if (!settings?.statusLine) return null;
|
|
79
|
+
const sl = settings.statusLine;
|
|
80
|
+
if (!sl.command) return null;
|
|
81
|
+
const match = sl.command.match(
|
|
82
|
+
/coding-friend-marketplace\/coding-friend\/([^/]+)\//
|
|
83
|
+
);
|
|
84
|
+
return match?.[1] ?? null;
|
|
85
|
+
}
|
|
86
|
+
function findLatestCacheVersion() {
|
|
87
|
+
const cachePath = pluginCachePath();
|
|
88
|
+
if (!existsSync(cachePath)) return null;
|
|
89
|
+
const versions = readdirSync(cachePath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
|
|
90
|
+
return versions[0] ?? null;
|
|
91
|
+
}
|
|
92
|
+
function updateStatusline(version) {
|
|
93
|
+
const cachePath = pluginCachePath();
|
|
94
|
+
const hookPath = `${cachePath}/${version}/hooks/statusline.sh`;
|
|
95
|
+
if (!existsSync(hookPath)) {
|
|
96
|
+
log.warn(`Statusline hook not found for v${version}`);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const settingsPath = claudeSettingsPath();
|
|
100
|
+
const settings = readJson(settingsPath) ?? {};
|
|
101
|
+
settings.statusLine = {
|
|
102
|
+
type: "command",
|
|
103
|
+
command: `bash ${hookPath}`
|
|
104
|
+
};
|
|
105
|
+
writeJson(settingsPath, settings);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
async function updateCommand(opts) {
|
|
109
|
+
const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
|
|
110
|
+
const doCli = updateAll || !!opts.cli;
|
|
111
|
+
const doPlugin = updateAll || !!opts.plugin;
|
|
112
|
+
const doStatusline = updateAll || !!opts.statusline;
|
|
113
|
+
console.log("=== \u{1F33F} Coding Friend Update \u{1F33F} ===");
|
|
114
|
+
console.log();
|
|
115
|
+
const currentVersion = getInstalledVersion();
|
|
116
|
+
const latestVersion = getLatestVersion();
|
|
117
|
+
const statuslineVersion = getStatuslineVersion();
|
|
118
|
+
const cliVersion = getCliVersion();
|
|
119
|
+
const latestCliVersion = getLatestCliVersion();
|
|
120
|
+
log.info(`Plugin version: ${currentVersion ? `v${currentVersion}` : chalk.yellow("not found")}`);
|
|
121
|
+
log.info(`Latest plugin version: ${latestVersion ? chalk.green(`v${latestVersion}`) : chalk.yellow("unknown (cannot reach GitHub)")}`);
|
|
122
|
+
log.info(`CLI version: v${cliVersion}`);
|
|
123
|
+
log.info(`Latest CLI version: ${latestCliVersion ? chalk.green(`v${latestCliVersion}`) : chalk.yellow("unknown (cannot reach npm)")}`);
|
|
124
|
+
log.info(
|
|
125
|
+
`Statusline version: ${statuslineVersion ? chalk.green(`v${statuslineVersion}`) : chalk.yellow("not configured")}`
|
|
126
|
+
);
|
|
127
|
+
console.log();
|
|
128
|
+
if (doPlugin) {
|
|
129
|
+
if (!latestVersion) {
|
|
130
|
+
log.warn(
|
|
131
|
+
"Cannot check latest plugin version. Verify manually at https://github.com/dinhanhthi/coding-friend/releases"
|
|
132
|
+
);
|
|
133
|
+
} else if (currentVersion === latestVersion) {
|
|
134
|
+
log.success(`Plugin already on the latest version (${chalk.green(`v${latestVersion}`)}).`);
|
|
135
|
+
} else {
|
|
136
|
+
log.step(`Plugin update available: ${chalk.yellow(`v${currentVersion}`)} \u2192 ${chalk.green(`v${latestVersion}`)}`);
|
|
137
|
+
if (!commandExists("claude")) {
|
|
138
|
+
log.error(
|
|
139
|
+
"Claude CLI not found. Install it first, or run: claude plugin update coding-friend@coding-friend-marketplace"
|
|
140
|
+
);
|
|
141
|
+
} else {
|
|
142
|
+
log.step("Updating plugin...");
|
|
143
|
+
const result = run("claude", [
|
|
144
|
+
"plugin",
|
|
145
|
+
"update",
|
|
146
|
+
"coding-friend@coding-friend-marketplace"
|
|
147
|
+
]);
|
|
148
|
+
if (result === null) {
|
|
149
|
+
log.error("Plugin update failed. Try manually: claude plugin update coding-friend@coding-friend-marketplace");
|
|
150
|
+
} else {
|
|
151
|
+
log.success("Plugin updated!");
|
|
152
|
+
let newVersion = currentVersion;
|
|
153
|
+
for (let i = 0; i < 5; i++) {
|
|
154
|
+
newVersion = getInstalledVersion();
|
|
155
|
+
if (newVersion !== currentVersion) break;
|
|
156
|
+
if (i < 4) sleepSync(1e3);
|
|
157
|
+
}
|
|
158
|
+
if (newVersion !== currentVersion) {
|
|
159
|
+
log.success(`Plugin updated to ${chalk.green(`v${newVersion}`)}`);
|
|
160
|
+
} else {
|
|
161
|
+
log.warn(
|
|
162
|
+
"Version in installed_plugins.json unchanged. Cache may still have been updated."
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (doCli) {
|
|
170
|
+
if (!latestCliVersion) {
|
|
171
|
+
log.warn("Cannot check latest CLI version from npm.");
|
|
172
|
+
} else if (cliVersion === latestCliVersion) {
|
|
173
|
+
log.success(`CLI already on the latest version (${chalk.green(`v${latestCliVersion}`)}).`);
|
|
174
|
+
} else {
|
|
175
|
+
log.step(`CLI update available: ${chalk.yellow(`v${cliVersion}`)} \u2192 ${chalk.green(`v${latestCliVersion}`)}`);
|
|
176
|
+
log.step("Updating CLI...");
|
|
177
|
+
const result = run("npm", ["install", "-g", "coding-friend-cli@latest"]);
|
|
178
|
+
if (result === null) {
|
|
179
|
+
log.error("CLI update failed. Try manually: npm install -g coding-friend-cli@latest");
|
|
180
|
+
} else {
|
|
181
|
+
log.success(`CLI updated to ${chalk.green(`v${latestCliVersion}`)}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (doStatusline) {
|
|
186
|
+
const targetVersion = findLatestCacheVersion();
|
|
187
|
+
if (targetVersion) {
|
|
188
|
+
log.step("Updating statusline...");
|
|
189
|
+
if (updateStatusline(targetVersion)) {
|
|
190
|
+
log.success(`Statusline updated to ${chalk.green(`v${targetVersion}`)}`);
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
log.warn("No cached plugin version found for statusline update.");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
ensureShellCompletion({ silent: false });
|
|
197
|
+
console.log();
|
|
198
|
+
log.dim("Restart Claude Code (or start a new session) to see changes.");
|
|
199
|
+
}
|
|
200
|
+
export {
|
|
201
|
+
updateCommand
|
|
202
|
+
};
|
package/package.json
CHANGED
package/dist/update-6PPVL2KJ.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureShellCompletion
|
|
3
|
-
} from "./chunk-VHZQ6KEU.js";
|
|
4
|
-
import {
|
|
5
|
-
commandExists,
|
|
6
|
-
run,
|
|
7
|
-
sleepSync
|
|
8
|
-
} from "./chunk-UFGNO6CW.js";
|
|
9
|
-
import {
|
|
10
|
-
claudeSettingsPath,
|
|
11
|
-
installedPluginsPath,
|
|
12
|
-
pluginCachePath
|
|
13
|
-
} from "./chunk-AQXTNLQD.js";
|
|
14
|
-
import {
|
|
15
|
-
log
|
|
16
|
-
} from "./chunk-6DUFTBTO.js";
|
|
17
|
-
import {
|
|
18
|
-
readJson,
|
|
19
|
-
writeJson
|
|
20
|
-
} from "./chunk-IUTXHCP7.js";
|
|
21
|
-
|
|
22
|
-
// src/commands/update.ts
|
|
23
|
-
import { existsSync, readdirSync } from "fs";
|
|
24
|
-
import chalk from "chalk";
|
|
25
|
-
function getInstalledVersion() {
|
|
26
|
-
const data = readJson(installedPluginsPath());
|
|
27
|
-
if (!data) return null;
|
|
28
|
-
const plugins = data.plugins ?? data;
|
|
29
|
-
for (const [key, value] of Object.entries(plugins)) {
|
|
30
|
-
if (!key.includes("coding-friend")) continue;
|
|
31
|
-
if (Array.isArray(value) && value.length > 0) {
|
|
32
|
-
const entry = value[0];
|
|
33
|
-
if (typeof entry.version === "string") return entry.version;
|
|
34
|
-
}
|
|
35
|
-
if (typeof value === "object" && value !== null && "version" in value) {
|
|
36
|
-
return value.version;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
function getLatestVersion() {
|
|
42
|
-
let tag = run("gh", [
|
|
43
|
-
"api",
|
|
44
|
-
"repos/dinhanhthi/coding-friend/releases/latest",
|
|
45
|
-
"--jq",
|
|
46
|
-
".tag_name"
|
|
47
|
-
]);
|
|
48
|
-
if (!tag) {
|
|
49
|
-
const json = run("curl", [
|
|
50
|
-
"-s",
|
|
51
|
-
"https://api.github.com/repos/dinhanhthi/coding-friend/releases/latest"
|
|
52
|
-
]);
|
|
53
|
-
if (json) {
|
|
54
|
-
try {
|
|
55
|
-
const data = JSON.parse(json);
|
|
56
|
-
tag = data.tag_name;
|
|
57
|
-
} catch {
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (!tag) return null;
|
|
62
|
-
return tag.replace(/^v/, "");
|
|
63
|
-
}
|
|
64
|
-
function getStatuslineVersion() {
|
|
65
|
-
const settings = readJson(claudeSettingsPath());
|
|
66
|
-
if (!settings?.statusLine) return null;
|
|
67
|
-
const sl = settings.statusLine;
|
|
68
|
-
if (!sl.command) return null;
|
|
69
|
-
const match = sl.command.match(
|
|
70
|
-
/coding-friend-marketplace\/coding-friend\/([^/]+)\//
|
|
71
|
-
);
|
|
72
|
-
return match?.[1] ?? null;
|
|
73
|
-
}
|
|
74
|
-
function findLatestCacheVersion() {
|
|
75
|
-
const cachePath = pluginCachePath();
|
|
76
|
-
if (!existsSync(cachePath)) return null;
|
|
77
|
-
const versions = readdirSync(cachePath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse();
|
|
78
|
-
return versions[0] ?? null;
|
|
79
|
-
}
|
|
80
|
-
function updateStatusline(version) {
|
|
81
|
-
const cachePath = pluginCachePath();
|
|
82
|
-
const hookPath = `${cachePath}/${version}/hooks/statusline.sh`;
|
|
83
|
-
if (!existsSync(hookPath)) {
|
|
84
|
-
log.warn(`Statusline hook not found for v${version}`);
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
const settingsPath = claudeSettingsPath();
|
|
88
|
-
const settings = readJson(settingsPath) ?? {};
|
|
89
|
-
settings.statusLine = {
|
|
90
|
-
type: "command",
|
|
91
|
-
command: `bash ${hookPath}`
|
|
92
|
-
};
|
|
93
|
-
writeJson(settingsPath, settings);
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
async function updateCommand() {
|
|
97
|
-
console.log("=== \u{1F33F} Coding Friend Update \u{1F33F} ===");
|
|
98
|
-
console.log();
|
|
99
|
-
const currentVersion = getInstalledVersion();
|
|
100
|
-
const latestVersion = getLatestVersion();
|
|
101
|
-
const statuslineVersion = getStatuslineVersion();
|
|
102
|
-
log.info(`Installed version: ${currentVersion ? chalk.green(`v${currentVersion}`) : chalk.yellow("not found")}`);
|
|
103
|
-
log.info(`Latest version: ${latestVersion ? chalk.green(`v${latestVersion}`) : chalk.yellow("unknown (cannot reach GitHub)")}`);
|
|
104
|
-
log.info(
|
|
105
|
-
`Statusline version: ${statuslineVersion ? chalk.green(`v${statuslineVersion}`) : chalk.yellow("not configured")}`
|
|
106
|
-
);
|
|
107
|
-
console.log();
|
|
108
|
-
if (!latestVersion) {
|
|
109
|
-
log.warn(
|
|
110
|
-
"Cannot check latest version. Verify manually at https://github.com/dinhanhthi/coding-friend/releases"
|
|
111
|
-
);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
const isUpToDate = currentVersion === latestVersion;
|
|
115
|
-
const statuslineMismatch = statuslineVersion !== null && statuslineVersion !== (currentVersion ?? latestVersion);
|
|
116
|
-
if (isUpToDate && !statuslineMismatch) {
|
|
117
|
-
log.success(`Already on the latest version (${chalk.green(`v${latestVersion}`)}). No update needed.`);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
if (!isUpToDate) {
|
|
121
|
-
log.step(`Update available: ${chalk.yellow(`v${currentVersion}`)} \u2192 ${chalk.green(`v${latestVersion}`)}`);
|
|
122
|
-
if (!commandExists("claude")) {
|
|
123
|
-
log.error(
|
|
124
|
-
"Claude CLI not found. Install it first, or run: claude plugin update coding-friend@coding-friend-marketplace"
|
|
125
|
-
);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
log.step("Updating plugin...");
|
|
129
|
-
const result = run("claude", [
|
|
130
|
-
"plugin",
|
|
131
|
-
"update",
|
|
132
|
-
"coding-friend@coding-friend-marketplace"
|
|
133
|
-
]);
|
|
134
|
-
if (result === null) {
|
|
135
|
-
log.error("Plugin update failed. Try manually: claude plugin update coding-friend@coding-friend-marketplace");
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
log.success("Plugin updated!");
|
|
139
|
-
let newVersion = currentVersion;
|
|
140
|
-
for (let i = 0; i < 5; i++) {
|
|
141
|
-
newVersion = getInstalledVersion();
|
|
142
|
-
if (newVersion !== currentVersion) break;
|
|
143
|
-
if (i < 4) sleepSync(1e3);
|
|
144
|
-
}
|
|
145
|
-
if (newVersion !== currentVersion) {
|
|
146
|
-
log.success(`Updated to ${chalk.green(`v${newVersion}`)}`);
|
|
147
|
-
} else {
|
|
148
|
-
log.warn(
|
|
149
|
-
"Version in installed_plugins.json unchanged. Cache may still have been updated."
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const targetVersion = findLatestCacheVersion();
|
|
154
|
-
if (targetVersion) {
|
|
155
|
-
log.step("Updating statusline...");
|
|
156
|
-
if (updateStatusline(targetVersion)) {
|
|
157
|
-
log.success(`Statusline updated to ${chalk.green(`v${targetVersion}`)}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
ensureShellCompletion({ silent: false });
|
|
161
|
-
console.log();
|
|
162
|
-
log.dim("Restart Claude Code (or start a new session) to see changes.");
|
|
163
|
-
}
|
|
164
|
-
export {
|
|
165
|
-
updateCommand
|
|
166
|
-
};
|