open-plan-annotator 1.1.3 → 1.1.5
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": "Interactive plan annotation plugin for Claude Code",
|
|
8
|
-
"version": "1.1.
|
|
8
|
+
"version": "1.1.5"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "open-plan-annotator",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Interactive plan annotation UI: review, strikethrough, and comment on Claude's plans before approving. Fully local, no external services.",
|
|
15
|
-
"version": "1.1.
|
|
15
|
+
"version": "1.1.5",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "ndom91"
|
|
18
18
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-plan-annotator",
|
|
3
3
|
"description": "Interactive plan annotation UI: review, strikethrough, and comment on Claude's plans before approving. Fully local, no external services.",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.5",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ndom91"
|
|
7
7
|
},
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/open-plan-annotator)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -8,7 +8,7 @@ import { buildCliHelpText, buildUnknownCommandPrefix } from "../shared/cliHelp.m
|
|
|
8
8
|
import { resolveCliMode } from "../shared/cliMode.mjs";
|
|
9
9
|
import { detectPackageManager } from "../shared/packageManager.mjs";
|
|
10
10
|
import { resolveRuntimeBinary } from "../shared/runtimeResolver.mjs";
|
|
11
|
-
import {
|
|
11
|
+
import { buildUpdateMessage } from "../shared/updateMessage.mjs";
|
|
12
12
|
|
|
13
13
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
14
|
const VERSION = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8")).version;
|
|
@@ -27,7 +27,7 @@ if (cliMode === "help") {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (cliMode === "doctor") {
|
|
30
|
-
printDoctor();
|
|
30
|
+
await printDoctor();
|
|
31
31
|
process.exit(0);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -51,7 +51,12 @@ if (cliMode === "hook") {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (cliMode === "update") {
|
|
54
|
-
console.log(
|
|
54
|
+
console.log(
|
|
55
|
+
await buildUpdateMessage({
|
|
56
|
+
currentVersion: VERSION,
|
|
57
|
+
packageManager: detectPackageManager({ installPath: fileURLToPath(import.meta.url) }),
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
55
60
|
process.exit(0);
|
|
56
61
|
}
|
|
57
62
|
|
|
@@ -118,8 +123,10 @@ child.on("error", (err) => {
|
|
|
118
123
|
process.exit(1);
|
|
119
124
|
});
|
|
120
125
|
|
|
121
|
-
function printDoctor() {
|
|
126
|
+
async function printDoctor() {
|
|
122
127
|
const platformKey = `${process.platform}-${process.arch}`;
|
|
128
|
+
const packageManager = detectPackageManager({ installPath: fileURLToPath(import.meta.url) });
|
|
129
|
+
const latestVersionLine = `update: ${await buildUpdateMessage({ currentVersion: VERSION, packageManager })}`;
|
|
123
130
|
|
|
124
131
|
try {
|
|
125
132
|
const runtime = resolveRuntimeBinary({ parentUrl: import.meta.url });
|
|
@@ -128,7 +135,7 @@ function printDoctor() {
|
|
|
128
135
|
`platform: ${platformKey}`,
|
|
129
136
|
`runtime package: ${runtime.packageName}`,
|
|
130
137
|
`runtime path: ${runtime.binaryPath}`,
|
|
131
|
-
|
|
138
|
+
latestVersionLine,
|
|
132
139
|
].join("\n"));
|
|
133
140
|
} catch (error) {
|
|
134
141
|
console.log([
|
|
@@ -136,7 +143,7 @@ function printDoctor() {
|
|
|
136
143
|
`platform: ${platformKey}`,
|
|
137
144
|
`runtime: missing`,
|
|
138
145
|
`error: ${error instanceof Error ? error.message : String(error)}`,
|
|
139
|
-
|
|
146
|
+
latestVersionLine,
|
|
140
147
|
].join("\n"));
|
|
141
148
|
}
|
|
142
149
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-plan-annotator",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Fully local plugin for interactive plan annotation from your Agentic assistants",
|
|
6
6
|
"author": "ndom91",
|
|
@@ -29,8 +29,10 @@
|
|
|
29
29
|
"shared/cliHelp.mjs",
|
|
30
30
|
"shared/cliMode.mjs",
|
|
31
31
|
"shared/packageManager.mjs",
|
|
32
|
+
"shared/updateMessage.mjs",
|
|
32
33
|
"shared/runtimeResolver.mjs",
|
|
33
34
|
"shared/updateHints.mjs",
|
|
35
|
+
"shared/versionInfo.mjs",
|
|
34
36
|
".claude-plugin/",
|
|
35
37
|
"opencode/bridge.js",
|
|
36
38
|
"opencode/config.js",
|
|
@@ -67,9 +69,9 @@
|
|
|
67
69
|
"@opencode-ai/plugin": "^1.2.14"
|
|
68
70
|
},
|
|
69
71
|
"optionalDependencies": {
|
|
70
|
-
"@open-plan-annotator/runtime-darwin-arm64": "1.1.
|
|
71
|
-
"@open-plan-annotator/runtime-darwin-x64": "1.1.
|
|
72
|
-
"@open-plan-annotator/runtime-linux-arm64": "1.1.
|
|
73
|
-
"@open-plan-annotator/runtime-linux-x64": "1.1.
|
|
72
|
+
"@open-plan-annotator/runtime-darwin-arm64": "1.1.5",
|
|
73
|
+
"@open-plan-annotator/runtime-darwin-x64": "1.1.5",
|
|
74
|
+
"@open-plan-annotator/runtime-linux-arm64": "1.1.5",
|
|
75
|
+
"@open-plan-annotator/runtime-linux-x64": "1.1.5"
|
|
74
76
|
}
|
|
75
77
|
}
|
package/shared/updateHints.mjs
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
export function buildUpdateInstructions(options = {}) {
|
|
2
2
|
const host = options.host ?? process.env.OPEN_PLAN_HOST;
|
|
3
3
|
const packageManager = options.packageManager ?? "npm";
|
|
4
|
+
const version = options.version ?? "latest";
|
|
4
5
|
|
|
5
6
|
if (host === "opencode") {
|
|
6
|
-
return "Refresh the OpenCode plugin install
|
|
7
|
+
return "Refresh the OpenCode plugin install and restart OpenCode.";
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
if (host === "claude-code") {
|
|
10
|
-
return "Refresh the Claude Code plugin or marketplace install
|
|
11
|
+
return "Refresh the Claude Code plugin or marketplace install and restart Claude Code.";
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
if (packageManager === "pnpm") {
|
|
15
|
+
return `Run \`pnpm i -g open-plan-annotator@${version}\`.`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (packageManager === "bun") {
|
|
19
|
+
return `Run \`bun add -g open-plan-annotator@${version}\`.`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return `Run \`npm i -g open-plan-annotator@${version}\`.`;
|
|
14
23
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { buildUpdateInstructions } from "./updateHints.mjs";
|
|
2
|
+
import { fetchLatestVersion, isNewerVersion } from "./versionInfo.mjs";
|
|
3
|
+
|
|
4
|
+
export async function buildUpdateMessage(options = {}) {
|
|
5
|
+
const currentVersion = options.currentVersion;
|
|
6
|
+
const packageManager = options.packageManager ?? "npm";
|
|
7
|
+
const host = options.host ?? process.env.OPEN_PLAN_HOST;
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const latestVersion = await fetchLatestVersion();
|
|
11
|
+
if (currentVersion && isNewerVersion(currentVersion, latestVersion)) {
|
|
12
|
+
return `latest v${latestVersion}; ${buildUpdateInstructions({ host, packageManager, version: latestVersion })}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (currentVersion) {
|
|
16
|
+
return `latest v${latestVersion}; already up to date`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return buildUpdateInstructions({ host, packageManager, version: latestVersion });
|
|
20
|
+
} catch {
|
|
21
|
+
return currentVersion
|
|
22
|
+
? `latest unknown; ${buildUpdateInstructions({ host, packageManager })}`
|
|
23
|
+
: buildUpdateInstructions({ host, packageManager });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org";
|
|
2
|
+
|
|
3
|
+
export function normalizeVersion(version) {
|
|
4
|
+
return version.trim().replace(/^v/, "");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function parseSemver(version) {
|
|
8
|
+
const normalized = normalizeVersion(version);
|
|
9
|
+
const match = normalized.match(/^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/);
|
|
10
|
+
if (!match) return null;
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
major: Number.parseInt(match[1], 10),
|
|
14
|
+
minor: Number.parseInt(match[2], 10),
|
|
15
|
+
patch: Number.parseInt(match[3], 10),
|
|
16
|
+
prerelease: match[4] ? match[4].split(".") : [],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function comparePrereleaseIdentifier(a, b) {
|
|
21
|
+
const aIsNum = /^[0-9]+$/.test(a);
|
|
22
|
+
const bIsNum = /^[0-9]+$/.test(b);
|
|
23
|
+
|
|
24
|
+
if (aIsNum && bIsNum) {
|
|
25
|
+
const aNum = Number.parseInt(a, 10);
|
|
26
|
+
const bNum = Number.parseInt(b, 10);
|
|
27
|
+
return aNum === bNum ? 0 : aNum > bNum ? 1 : -1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (aIsNum) return -1;
|
|
31
|
+
if (bIsNum) return 1;
|
|
32
|
+
if (a === b) return 0;
|
|
33
|
+
return a > b ? 1 : -1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function compareSemver(a, b) {
|
|
37
|
+
const parsedA = parseSemver(a);
|
|
38
|
+
const parsedB = parseSemver(b);
|
|
39
|
+
if (!parsedA || !parsedB) return 0;
|
|
40
|
+
|
|
41
|
+
if (parsedA.major !== parsedB.major) return parsedA.major > parsedB.major ? 1 : -1;
|
|
42
|
+
if (parsedA.minor !== parsedB.minor) return parsedA.minor > parsedB.minor ? 1 : -1;
|
|
43
|
+
if (parsedA.patch !== parsedB.patch) return parsedA.patch > parsedB.patch ? 1 : -1;
|
|
44
|
+
|
|
45
|
+
if (parsedA.prerelease.length === 0 && parsedB.prerelease.length === 0) return 0;
|
|
46
|
+
if (parsedA.prerelease.length === 0) return 1;
|
|
47
|
+
if (parsedB.prerelease.length === 0) return -1;
|
|
48
|
+
|
|
49
|
+
const maxLen = Math.max(parsedA.prerelease.length, parsedB.prerelease.length);
|
|
50
|
+
for (let i = 0; i < maxLen; i += 1) {
|
|
51
|
+
const aPart = parsedA.prerelease[i];
|
|
52
|
+
const bPart = parsedB.prerelease[i];
|
|
53
|
+
if (aPart === undefined) return -1;
|
|
54
|
+
if (bPart === undefined) return 1;
|
|
55
|
+
const diff = comparePrereleaseIdentifier(aPart, bPart);
|
|
56
|
+
if (diff !== 0) return diff;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function isNewerVersion(current, latest) {
|
|
63
|
+
const parsedCurrent = parseSemver(current);
|
|
64
|
+
const parsedLatest = parseSemver(latest);
|
|
65
|
+
if (!parsedCurrent || !parsedLatest) return false;
|
|
66
|
+
return compareSemver(latest, current) > 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function fetchLatestVersion(packageName = "open-plan-annotator") {
|
|
70
|
+
const response = await fetch(`${NPM_REGISTRY_BASE_URL}/${encodeURIComponent(packageName)}/latest`, {
|
|
71
|
+
headers: { "User-Agent": "open-plan-annotator-update-check", Accept: "application/json" },
|
|
72
|
+
signal: AbortSignal.timeout(10_000),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error(`npm registry responded with ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const payload = await response.json();
|
|
80
|
+
if (!payload || typeof payload !== "object" || typeof payload.version !== "string") {
|
|
81
|
+
throw new Error("npm registry response did not include a version string");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return normalizeVersion(payload.version);
|
|
85
|
+
}
|