@ramarivera/coding-buddy 0.9.3 → 0.9.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.
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "Persistent coding companion for Claude Code, Pi, and Oh My Pi (requires bun: https://bun.sh/install)",
|
|
8
|
-
"version": "0.
|
|
8
|
+
"version": "0.9.4"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "coding-buddy",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Persistent coding companion for Claude Code, Pi, and Oh My Pi. MCP-based terminal pet with ASCII art, stats, reactions, and personality. Requires bun runtime (https://bun.sh/install).",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.9.4",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "ramarivera"
|
|
18
18
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramarivera/coding-buddy",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Persistent coding companion for Claude Code, Pi, and Oh My Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"omp": {
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"test": "bun test",
|
|
37
37
|
"typecheck": "tsc --noEmit",
|
|
38
38
|
"gen:emoji-widths": "bun run scripts/gen-emoji-widths.ts",
|
|
39
|
+
"sync-version": "bun run scripts/sync-version.ts",
|
|
40
|
+
"version": "bun run sync-version && git add .claude-plugin",
|
|
39
41
|
"ci:statusline": "bash scripts/ci/check-statusline.sh",
|
|
40
42
|
"ci:vhs:render": "bash scripts/ci/render-vhs-goldens.sh",
|
|
41
43
|
"ci:vhs:update": "bash scripts/ci/render-vhs-goldens.sh --update",
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync every version field in the repo to package.json.
|
|
3
|
+
*
|
|
4
|
+
* bun run sync-version # rewrite drifted fields
|
|
5
|
+
* bun run sync-version --check # exit 1 on drift, change nothing (CI)
|
|
6
|
+
*
|
|
7
|
+
* Wired into the npm `version` lifecycle so `npm version <bump>` updates the
|
|
8
|
+
* manifests in the same commit as package.json, and into CI via --check so
|
|
9
|
+
* drift cannot land.
|
|
10
|
+
*
|
|
11
|
+
* Design and the original implementation come from #110 by @grlee. That PR
|
|
12
|
+
* conflicted with main and lives on a fork, so it is reimplemented here rather
|
|
13
|
+
* than rebased.
|
|
14
|
+
*
|
|
15
|
+
* server/index.ts is deliberately NOT a target — it imports pkg.version
|
|
16
|
+
* directly, which is strictly better than syncing a literal. Anything that can
|
|
17
|
+
* import package.json should do that instead of being added below.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
21
|
+
import { join } from "path";
|
|
22
|
+
|
|
23
|
+
const ROOT = join(import.meta.dir, "..");
|
|
24
|
+
const CHECK_ONLY = process.argv.includes("--check");
|
|
25
|
+
|
|
26
|
+
const version: unknown = JSON.parse(
|
|
27
|
+
readFileSync(join(ROOT, "package.json"), "utf8"),
|
|
28
|
+
).version;
|
|
29
|
+
|
|
30
|
+
if (typeof version !== "string" || version === "") {
|
|
31
|
+
console.error("sync-version: package.json is missing a version field");
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Target {
|
|
36
|
+
/** Repo-relative path. */
|
|
37
|
+
path: string;
|
|
38
|
+
/** Every version field in the document, for reporting and for rewriting. */
|
|
39
|
+
fields: (doc: any) => { label: string; get: () => string; set: () => void }[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const TARGETS: Target[] = [
|
|
43
|
+
{
|
|
44
|
+
path: ".claude-plugin/plugin.json",
|
|
45
|
+
fields: (doc) => [
|
|
46
|
+
{ label: "version", get: () => doc.version, set: () => { doc.version = version; } },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
path: ".claude-plugin/marketplace.json",
|
|
51
|
+
fields: (doc) => [
|
|
52
|
+
{
|
|
53
|
+
label: "metadata.version",
|
|
54
|
+
get: () => doc.metadata?.version,
|
|
55
|
+
// Creates metadata if absent. Guarding the write instead would let
|
|
56
|
+
// --check report drift that the fixer could never resolve.
|
|
57
|
+
set: () => {
|
|
58
|
+
doc.metadata ??= {};
|
|
59
|
+
doc.metadata.version = version;
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
...(doc.plugins ?? []).map((plugin: any, i: number) => ({
|
|
63
|
+
label: `plugins[${i}].version`,
|
|
64
|
+
get: () => plugin.version,
|
|
65
|
+
set: () => { plugin.version = version; },
|
|
66
|
+
})),
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
export interface Drift {
|
|
72
|
+
path: string;
|
|
73
|
+
label: string;
|
|
74
|
+
current: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Returns every field that disagrees with package.json. Never writes. */
|
|
78
|
+
export function findDrift(): Drift[] {
|
|
79
|
+
const drift: Drift[] = [];
|
|
80
|
+
for (const target of TARGETS) {
|
|
81
|
+
const doc = JSON.parse(readFileSync(join(ROOT, target.path), "utf8"));
|
|
82
|
+
for (const field of target.fields(doc)) {
|
|
83
|
+
const current = field.get();
|
|
84
|
+
if (current !== version) drift.push({ path: target.path, label: field.label, current });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return drift;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function main(): void {
|
|
91
|
+
const drift = findDrift();
|
|
92
|
+
|
|
93
|
+
for (const d of drift) {
|
|
94
|
+
console.log(
|
|
95
|
+
`${CHECK_ONLY ? "DRIFT" : "sync"}: ${d.path} :: ${d.label} ${d.current} -> ${version}`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (drift.length === 0) {
|
|
100
|
+
console.log(`sync-version: all version fields already at ${version}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (CHECK_ONLY) {
|
|
105
|
+
console.error(
|
|
106
|
+
"sync-version: version fields are out of sync with package.json. Run `bun run sync-version`.",
|
|
107
|
+
);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Rewrite only the files that actually drifted, preserving 4-space style.
|
|
112
|
+
const drifted = new Set(drift.map((d) => d.path));
|
|
113
|
+
for (const target of TARGETS) {
|
|
114
|
+
if (!drifted.has(target.path)) continue;
|
|
115
|
+
const full = join(ROOT, target.path);
|
|
116
|
+
const doc = JSON.parse(readFileSync(full, "utf8"));
|
|
117
|
+
for (const field of target.fields(doc)) field.set();
|
|
118
|
+
writeFileSync(full, `${JSON.stringify(doc, null, 4)}\n`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (import.meta.main) main();
|
package/server/index.ts
CHANGED
|
@@ -11,6 +11,9 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { existsSync } from "fs";
|
|
13
13
|
import { join, resolve, dirname } from "path";
|
|
14
|
+
// The version advertised in the MCP handshake. Imported rather than written
|
|
15
|
+
// as a literal so it cannot drift from the published package (it had, to 0.6.0).
|
|
16
|
+
import pkg from "../package.json" with { type: "json" };
|
|
14
17
|
|
|
15
18
|
import { generateBones,
|
|
16
19
|
generatePersonality,
|
|
@@ -125,7 +128,7 @@ function getInstructions(): string {
|
|
|
125
128
|
const server = new McpServer(
|
|
126
129
|
{
|
|
127
130
|
name: "coding-buddy",
|
|
128
|
-
version:
|
|
131
|
+
version: pkg.version,
|
|
129
132
|
},
|
|
130
133
|
{
|
|
131
134
|
instructions: getInstructions(),
|