@graphit/cli 0.2.365 → 0.2.371
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/bin/graphit +1 -1
- package/bin/graphit.ps1 +1 -1
- package/dist/commands/dashboard-entities.d.ts +14 -0
- package/dist/commands/dashboard-entities.js +140 -0
- package/dist/commands/dashboard-entities.js.map +1 -0
- package/dist/commands/dashboard.d.ts +1 -14
- package/dist/commands/dashboard.js +6 -135
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/ds/api.js +2 -9
- package/dist/commands/ds/api.js.map +1 -1
- package/dist/commands/ds/delete.d.ts +2 -0
- package/dist/commands/ds/delete.js +35 -0
- package/dist/commands/ds/delete.js.map +1 -0
- package/dist/commands/ds/polling.js +11 -10
- package/dist/commands/ds/polling.js.map +1 -1
- package/dist/commands/ds/render.d.ts +3 -2
- package/dist/commands/ds/render.js +21 -20
- package/dist/commands/ds/render.js.map +1 -1
- package/dist/commands/ds/types.d.ts +17 -8
- package/dist/commands/ds/types.js.map +1 -1
- package/dist/commands/ds/ui-only.js +2 -9
- package/dist/commands/ds/ui-only.js.map +1 -1
- package/dist/commands/ds-poll.js +4 -7
- package/dist/commands/ds-poll.js.map +1 -1
- package/dist/commands/ds.js +40 -27
- package/dist/commands/ds.js.map +1 -1
- package/dist/update-check.d.ts +12 -0
- package/dist/update-check.js +36 -16
- package/dist/update-check.js.map +1 -1
- package/package.json +6 -4
- package/scripts/plugin-status.mjs +49 -18
- package/scripts/sync-plugin-marketplace.sh +62 -15
- package/scripts/sync-plugin-version.mjs +7 -2
- package/scripts/sync-workflow-references.mjs +61 -0
- package/scripts/verb-policy-source.json +3 -3
- package/skills/graphit/SKILL.md +59 -101
- package/skills/graphit/VERSION.json +1 -1
- package/skills/graphit/references/build.md +37 -0
- package/skills/graphit/references/dashboard-create.md +20 -5
- package/skills/graphit/references/dashboard-planning.md +2 -2
- package/skills/graphit/references/data-sources.md +6 -4
- package/skills/graphit/references/explore.md +21 -0
- package/skills/graphit/references/filters.md +2 -2
- package/skills/graphit/references/install-update.md +5 -2
- package/skills/graphit/references/kb-discovery.md +3 -1
- package/skills/graphit/references/kb-scope.md +12 -1
- package/skills/graphit/references/onboarding.md +6 -12
- package/skills/graphit/references/operations.md +6 -9
- package/skills/graphit/references/query-contract.md +52 -0
- package/skills/graphit/references/runtime.md +2 -2
- package/skills/graphit/references/semantic-authoring.md +1 -1
- package/skills/graphit/references/share.md +46 -0
- package/skills/graphit/references/sharing-recovery.md +2 -0
- package/skills/graphit-build/SKILL.md +66 -0
- package/skills/graphit-explore/SKILL.md +50 -0
- package/skills/graphit-share/SKILL.md +75 -0
package/dist/update-check.d.ts
CHANGED
|
@@ -9,6 +9,18 @@ type InstallContext = "npx" | "global" | "local";
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function classifyInstallContext(selfPath: string, cwd: string): InstallContext;
|
|
11
11
|
export declare function getCurrentVersion(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Issue #994: the remedy for a stale CLI depends on who launched it. The Claude
|
|
14
|
+
* Code plugin's wrapper exports GRAPHIT_PLUGIN_ROOT and resolves npm latest once
|
|
15
|
+
* per session, so a newer release arrives in the next session on its own - and
|
|
16
|
+
* `npm install -g` there would create a global that shadows the wrapper on PATH.
|
|
17
|
+
* A pinned `npx -y @graphit/cli@<version>` (Codex, Cursor, CI) is also npx, but a
|
|
18
|
+
* new session reruns the same pin, so it keeps the pre-existing guidance.
|
|
19
|
+
*/
|
|
20
|
+
export type UpdateChannel = "plugin" | "global" | "other";
|
|
21
|
+
export declare function updateChannel(context: InstallContext, env?: NodeJS.ProcessEnv): UpdateChannel;
|
|
22
|
+
export declare function updateRemedy(channel: UpdateChannel): string;
|
|
23
|
+
export declare function formatUpdateBanner(channel: UpdateChannel, current: string, latest: string): string;
|
|
12
24
|
/**
|
|
13
25
|
* Issue #904: the one line that turns an uninterpretable failure into an
|
|
14
26
|
* actionable one, for the caller who is behind the server's contract.
|
package/dist/update-check.js
CHANGED
|
@@ -66,19 +66,22 @@ export function classifyInstallContext(selfPath, cwd) {
|
|
|
66
66
|
return "local";
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* a probe that cannot answer must read as "not global", never as a crash.
|
|
69
|
+
* How THIS binary was launched. One definition for every call site, and safe on
|
|
70
|
+
* the error path: `process.cwd()` throws ENOENT from an unlinked directory, and a
|
|
71
|
+
* probe that cannot answer reads as "local" (quiet, never global), never as a crash.
|
|
73
72
|
*/
|
|
74
|
-
function
|
|
73
|
+
function installContext() {
|
|
75
74
|
try {
|
|
76
|
-
return classifyInstallContext(fileURLToPath(import.meta.url), process.cwd())
|
|
75
|
+
return classifyInstallContext(fileURLToPath(import.meta.url), process.cwd());
|
|
77
76
|
}
|
|
78
77
|
catch {
|
|
79
|
-
return
|
|
78
|
+
return "local";
|
|
80
79
|
}
|
|
81
80
|
}
|
|
81
|
+
/** Whether THIS binary is a stale global install (the `npm i -g` shadowing the plugin's npx wrapper). */
|
|
82
|
+
function isGlobalInstall() {
|
|
83
|
+
return installContext() === "global";
|
|
84
|
+
}
|
|
82
85
|
function migrationNoticeAllowed() {
|
|
83
86
|
try {
|
|
84
87
|
if (!existsSync(MIGRATION_NOTICE_FILE))
|
|
@@ -136,6 +139,28 @@ function isNewer(latest, current) {
|
|
|
136
139
|
export function getCurrentVersion() {
|
|
137
140
|
return pkg.version;
|
|
138
141
|
}
|
|
142
|
+
export function updateChannel(context, env = process.env) {
|
|
143
|
+
if (context === "global")
|
|
144
|
+
return "global";
|
|
145
|
+
return env.GRAPHIT_PLUGIN_ROOT ? "plugin" : "other";
|
|
146
|
+
}
|
|
147
|
+
export function updateRemedy(channel) {
|
|
148
|
+
if (channel === "global")
|
|
149
|
+
return INSTALL_LATEST_COMMAND;
|
|
150
|
+
if (channel === "plugin")
|
|
151
|
+
return "start a new session - the plugin runs the newest CLI automatically";
|
|
152
|
+
return "your assistant's plugin manager";
|
|
153
|
+
}
|
|
154
|
+
export function formatUpdateBanner(channel, current, latest) {
|
|
155
|
+
if (channel === "plugin") {
|
|
156
|
+
return (`\n Graphit CLI update published: ${current} → ${latest}\n` +
|
|
157
|
+
" The plugin picks it up automatically in your next session - no install needed.\n\n");
|
|
158
|
+
}
|
|
159
|
+
return (`\n Graphit CLI update available: ${current} → ${latest}\n` +
|
|
160
|
+
` Update the CLI binary: ${INSTALL_LATEST_COMMAND}\n` +
|
|
161
|
+
" (If `graphit` is on a custom npm prefix, add --prefix <dir> for that prefix.)\n" +
|
|
162
|
+
" Your assistant's skill bundle updates separately via the plugin manager.\n\n");
|
|
163
|
+
}
|
|
139
164
|
/**
|
|
140
165
|
* Issue #904: the one line that turns an uninterpretable failure into an
|
|
141
166
|
* actionable one, for the caller who is behind the server's contract.
|
|
@@ -160,9 +185,7 @@ export function staleVersionHint() {
|
|
|
160
185
|
return undefined;
|
|
161
186
|
if (Date.now() - cache.checkedAt > HINT_MAX_AGE_MS)
|
|
162
187
|
return undefined;
|
|
163
|
-
const remedy =
|
|
164
|
-
? INSTALL_LATEST_COMMAND
|
|
165
|
-
: "your assistant's plugin manager";
|
|
188
|
+
const remedy = updateRemedy(updateChannel(installContext()));
|
|
166
189
|
return (`This CLI is ${current}; ${cache.latestVersion} is available. ` +
|
|
167
190
|
`The server's contract can move ahead of an older CLI - update (${remedy}) and retry.`);
|
|
168
191
|
}
|
|
@@ -172,12 +195,9 @@ export function printUpdateBanner() {
|
|
|
172
195
|
// Project #246: when running as the stale global, the self-announcing shim
|
|
173
196
|
// prints the migration notice instead - suppress the "npm install -g" banner so
|
|
174
197
|
// we don't tell the user to reinstall the very global we're asking them to remove.
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
writeStderr(
|
|
178
|
-
` Update the CLI binary: ${INSTALL_LATEST_COMMAND}\n` +
|
|
179
|
-
" (If `graphit` is on a custom npm prefix, add --prefix <dir> for that prefix.)\n" +
|
|
180
|
-
" Your assistant's skill bundle updates separately via the plugin manager.\n\n");
|
|
198
|
+
const channel = updateChannel(installContext());
|
|
199
|
+
if (channel !== "global" && cache && isNewer(cache.latestVersion, current)) {
|
|
200
|
+
writeStderr(formatUpdateBanner(channel, current, cache.latestVersion));
|
|
181
201
|
}
|
|
182
202
|
const skillBanner = formatSkillStalenessBanner(findOutdatedSkillInstalls(current), current);
|
|
183
203
|
if (skillBanner) {
|
package/dist/update-check.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE9D,MAAM,YAAY,GAAG,gDAAgD,CAAC;AACtE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;AACxD,MAAM,qBAAqB,GAAG,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;AACvE,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,4EAA4E;AAC5E,8EAA8E;AAC9E,uEAAuE;AACvE,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,CAAC;AACpC,2EAA2E;AAC3E,6DAA6D;AAC7D,MAAM,sBAAsB,GAAG,oCAAoC,CAAC;AAOpE,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,+EAA+E;AAC/E,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAEpC,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CACL,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ;QACnC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;QAC/B,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAChC,CAAC;AACJ,CAAC;AAID,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,SAAS,QAAQ,CAAC,KAAa,EAAE,MAAc;IAC7C,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,GAAW;IAClE,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,OAAO,GAAG,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,eAAe,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACpF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.371",
|
|
4
4
|
"description": "Graphit CLI - Build custom dashboards from any AI coding assistant",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,14 +12,16 @@
|
|
|
12
12
|
"graphit": "./dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
|
-
"build": "npm run sync:version && tsc",
|
|
15
|
+
"build": "npm run sync:version && npm run sync:workflows && tsc",
|
|
16
16
|
"dev": "tsx src/index.ts",
|
|
17
17
|
"lint": "npm run check:version && tsc --noEmit",
|
|
18
|
-
"test": "npm run build && npm run check:commands && node --test test/*.test.mjs",
|
|
18
|
+
"test": "npm run build && npm run check:commands && GRAPHIT_SKIP_PLUGIN_PREFLIGHT=1 node --test test/*.test.mjs",
|
|
19
19
|
"sync:version": "node scripts/sync-plugin-version.mjs",
|
|
20
|
+
"sync:workflows": "node scripts/sync-workflow-references.mjs",
|
|
21
|
+
"check:workflows": "node scripts/sync-workflow-references.mjs --check",
|
|
20
22
|
"check:version": "node scripts/sync-plugin-version.mjs --check",
|
|
21
23
|
"gen:commands": "node scripts/generate-commands-doc.mjs && node scripts/generate-tool-manifest.mjs",
|
|
22
|
-
"check:commands": "node scripts/generate-commands-doc.mjs --check && node scripts/generate-tool-manifest.mjs --check"
|
|
24
|
+
"check:commands": "node scripts/generate-commands-doc.mjs --check && node scripts/generate-tool-manifest.mjs --check && npm run check:workflows"
|
|
23
25
|
},
|
|
24
26
|
"engines": {
|
|
25
27
|
"node": ">=18"
|
|
@@ -50,11 +50,21 @@ const shouldRepair = args.has("--repair") || args.has("--auto-repair");
|
|
|
50
50
|
const isPreflight = args.has("--preflight");
|
|
51
51
|
const hookIndex = process.argv.indexOf("--hook");
|
|
52
52
|
const hookEvent = hookIndex >= 0 ? process.argv[hookIndex + 1] : null;
|
|
53
|
-
const
|
|
53
|
+
const pluginRootFromEnv =
|
|
54
54
|
process.env.CLAUDE_PLUGIN_ROOT ??
|
|
55
55
|
process.env.CODEX_PLUGIN_ROOT ??
|
|
56
|
-
process.env.GRAPHIT_PLUGIN_ROOT
|
|
57
|
-
|
|
56
|
+
process.env.GRAPHIT_PLUGIN_ROOT;
|
|
57
|
+
const pluginRoot = pluginRootFromEnv ?? dirname(dirname(fileURLToPath(import.meta.url)));
|
|
58
|
+
// Issue #994: a plugin root variable means this run inspects the bundle an
|
|
59
|
+
// assistant loaded (hooks get CLAUDE_PLUGIN_ROOT, the bin/graphit wrapper exports
|
|
60
|
+
// GRAPHIT_PLUGIN_ROOT). That bundle's CLI already tracks npm latest through npx, so
|
|
61
|
+
// a newer release means the BUNDLE is behind. Without one, this run inspects the
|
|
62
|
+
// npm package it ships in - a CLI launched without the plugin, i.e. a global install.
|
|
63
|
+
const inspectsPluginBundle = pluginRootFromEnv !== undefined;
|
|
64
|
+
const PLUGIN_UPDATE_STEPS =
|
|
65
|
+
"In Claude Code run `/plugin marketplace update graphit-plugin`, then `/plugin update graphit@graphit-plugin`, " +
|
|
66
|
+
"then restart Claude Code (asking to update Graphit runs the same steps via `/graphit:update`). " +
|
|
67
|
+
"In Codex, update the Graphit plugin through its plugin manager.";
|
|
58
68
|
// Project #246: the version cache must be shared between this SessionStart hook
|
|
59
69
|
// and the bin/graphit wrapper (agent Bash tool). CLAUDE_PLUGIN_DATA is set
|
|
60
70
|
// per-plugin/per-context by Claude Code and is NOT guaranteed identical across
|
|
@@ -629,10 +639,23 @@ async function collectStatus() {
|
|
|
629
639
|
const marketplace = bundleInfo.marketplace;
|
|
630
640
|
const marketplacePlugin = bundleInfo.marketplacePlugin;
|
|
631
641
|
|
|
642
|
+
// Issue #994: only the npm package (and the repo's cli/ dir) carries package.json
|
|
643
|
+
// and the npm-shaped marketplace.json that sync:version stamps. A bundle installed
|
|
644
|
+
// from the git marketplace ships that repo's own catalog (source "./", no
|
|
645
|
+
// metadata) by design, so the catalog checks are publisher checks - CI gates them
|
|
646
|
+
// (`check:version`, `sync-plugin-marketplace.sh verify`) - and a customer who hits
|
|
647
|
+
// real drift needs a plugin update, not a publish step.
|
|
648
|
+
const isPackageLayout = existsSync(join(pluginRoot, "package.json"));
|
|
649
|
+
const driftRemediation = isPackageLayout
|
|
650
|
+
? "Run `npm run sync:version` before publishing @graphit/cli."
|
|
651
|
+
: `This installed Graphit plugin bundle is inconsistent. Update or reinstall it: ${PLUGIN_UPDATE_STEPS}`;
|
|
652
|
+
|
|
632
653
|
const versionChecks = [
|
|
633
654
|
[".claude-plugin/plugin.json", claudePlugin?.version],
|
|
634
655
|
[".codex-plugin/plugin.json", codexPlugin?.version],
|
|
635
|
-
|
|
656
|
+
...(isPackageLayout
|
|
657
|
+
? [[".claude-plugin/marketplace.json metadata", marketplace?.metadata?.version]]
|
|
658
|
+
: []),
|
|
636
659
|
[".claude-plugin/marketplace.json plugin", marketplacePlugin?.version],
|
|
637
660
|
["skills/graphit/VERSION.json", tryReadJson(join(pluginRoot, "skills", "graphit", "VERSION.json"))?.version],
|
|
638
661
|
["skills/graphit/SKILL.md", readFrontmatterVersion(join(pluginRoot, "skills", "graphit", "SKILL.md"))],
|
|
@@ -646,39 +669,47 @@ async function collectStatus() {
|
|
|
646
669
|
findings.push({
|
|
647
670
|
type: "metadata-drift",
|
|
648
671
|
message: `${label} is ${version ?? "missing"}, expected ${currentVersion}`,
|
|
649
|
-
remediation:
|
|
672
|
+
remediation: driftRemediation,
|
|
650
673
|
});
|
|
651
674
|
}
|
|
652
675
|
metadata.push({ label, version: version ?? null });
|
|
653
676
|
}
|
|
654
677
|
|
|
655
678
|
const marketplaceSource = marketplacePlugin?.source;
|
|
656
|
-
const sourceMatches =
|
|
657
|
-
marketplaceSource?.source === "npm" &&
|
|
658
|
-
marketplaceSource.package === packageName &&
|
|
659
|
-
marketplaceSource.version === currentVersion;
|
|
660
679
|
metadata.push({
|
|
661
680
|
label: ".claude-plugin/marketplace.json source",
|
|
662
681
|
version: marketplaceSource?.version ?? null,
|
|
663
682
|
source: marketplaceSource ?? null,
|
|
664
683
|
});
|
|
665
|
-
|
|
684
|
+
const sourceMatches =
|
|
685
|
+
marketplaceSource?.source === "npm" &&
|
|
686
|
+
marketplaceSource.package === packageName &&
|
|
687
|
+
marketplaceSource.version === currentVersion;
|
|
688
|
+
if (!isPreflight && isPackageLayout && !sourceMatches) {
|
|
666
689
|
findings.push({
|
|
667
690
|
type: "metadata-drift",
|
|
668
691
|
message: `.claude-plugin/marketplace.json source is ${
|
|
669
692
|
marketplaceSource ? JSON.stringify(marketplaceSource) : "missing"
|
|
670
693
|
}, expected npm source ${packageName}@${currentVersion}`,
|
|
671
|
-
remediation:
|
|
694
|
+
remediation: driftRemediation,
|
|
672
695
|
});
|
|
673
696
|
}
|
|
674
697
|
|
|
675
698
|
const latestVersion = await getLatestVersion(currentVersion);
|
|
676
699
|
if (!isPreflight && latestVersion && compareVersions(latestVersion, currentVersion) > 0) {
|
|
677
|
-
findings.push(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
700
|
+
findings.push(
|
|
701
|
+
inspectsPluginBundle
|
|
702
|
+
? {
|
|
703
|
+
type: "plugin-update",
|
|
704
|
+
message: `Graphit plugin update available: ${currentVersion} -> ${latestVersion}`,
|
|
705
|
+
remediation: `The plugin runs the latest Graphit CLI automatically; what is behind is the plugin bundle itself (skills, hooks and commands at ${currentVersion}). ${PLUGIN_UPDATE_STEPS} Do not install @graphit/cli globally: a global install shadows the plugin's CLI on PATH.`,
|
|
706
|
+
}
|
|
707
|
+
: {
|
|
708
|
+
type: "package-update",
|
|
709
|
+
message: `@graphit/cli update available: ${currentVersion} -> ${latestVersion}`,
|
|
710
|
+
remediation: "This update is for the npm CLI binary (@graphit/cli), a separate artifact from the skill bundle. Update the binary with `npm install -g @graphit/cli@latest` (not `npm update -g`, which respects the original semver range and can miss the latest). If `graphit` resolves to a custom npm prefix (compare `command -v graphit` with `npm prefix -g`), reinstall to that prefix with `npm install -g @graphit/cli@latest --prefix <dir>` (<dir> = the parent of the bin dir holding graphit). The Claude Code/Codex skill bundle updates separately via `claude plugin update graphit@graphit-plugin` and does NOT update the binary.",
|
|
711
|
+
},
|
|
712
|
+
);
|
|
682
713
|
}
|
|
683
714
|
|
|
684
715
|
const claudeInstall = inspectClaudeInstalledPlugin(currentVersion, shouldRepair);
|
|
@@ -759,8 +790,8 @@ function buildHookNudges(status) {
|
|
|
759
790
|
) {
|
|
760
791
|
lines.push(
|
|
761
792
|
`- A newer Graphit plugin is available (${status.currentVersion} -> ${status.latestVersion}). ` +
|
|
762
|
-
"Tell the user once to update
|
|
763
|
-
"the CLI
|
|
793
|
+
"Tell the user once to update it with `/plugin marketplace update graphit-plugin`, then " +
|
|
794
|
+
"`/plugin update graphit@graphit-plugin`, then restart Claude Code; the CLI itself already runs the latest release.",
|
|
764
795
|
);
|
|
765
796
|
shown.push("plugin-update");
|
|
766
797
|
}
|
|
@@ -8,21 +8,18 @@ VERSION=$(node -p "require('./cli/package.json').version")
|
|
|
8
8
|
sync_marketplace() {
|
|
9
9
|
local target="$MARKETPLACE_DIR"
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# Mirror generated directories so removed files cannot linger downstream.
|
|
17
|
-
mkdir -p "$target/skills/graphit/references"
|
|
18
|
-
rsync -a --delete cli/skills/graphit/references/ "$target/skills/graphit/references/"
|
|
19
|
-
mkdir -p "$target/skills/graphit/cursor"
|
|
20
|
-
rsync -a --delete cli/skills/graphit/cursor/ "$target/skills/graphit/cursor/"
|
|
11
|
+
# Project #298: native workflows are siblings of the router. Mirror the
|
|
12
|
+
# entire authored skill tree so every host receives them and retired skills
|
|
13
|
+
# cannot linger. Hidden editor state is not plugin content.
|
|
14
|
+
mkdir -p "$target/skills"
|
|
15
|
+
rsync -a --delete --exclude='.*' cli/skills/ "$target/skills/"
|
|
21
16
|
mkdir -p "$target/hooks"
|
|
22
17
|
rsync -a --delete cli/hooks/ "$target/hooks/"
|
|
23
18
|
|
|
24
19
|
mkdir -p "$target/scripts"
|
|
25
|
-
|
|
20
|
+
# Project #298: the copied hook manifest must not reference absent scripts.
|
|
21
|
+
cp cli/scripts/plugin-status.mjs cli/scripts/block-legacy-setup.mjs \
|
|
22
|
+
cli/scripts/show-query-result.mjs "$target/scripts/"
|
|
26
23
|
|
|
27
24
|
# Project #246: the public plugin ships wrappers that invoke the current CLI.
|
|
28
25
|
mkdir -p "$target/bin"
|
|
@@ -84,13 +81,42 @@ verify_marketplace() {
|
|
|
84
81
|
fail=1
|
|
85
82
|
fi
|
|
86
83
|
|
|
84
|
+
# Check against the canonical manifest, so a damaged target cannot hide a dependency.
|
|
85
|
+
if ! node - "$target" <<'JS'
|
|
86
|
+
const fs = require("node:fs");
|
|
87
|
+
const path = require("node:path");
|
|
88
|
+
const target = process.argv[2];
|
|
89
|
+
const config = JSON.parse(fs.readFileSync("cli/hooks/hooks.json", "utf8"));
|
|
90
|
+
const prefix = "${CLAUDE_PLUGIN_ROOT}/";
|
|
91
|
+
const files = new Set(["hooks/hooks.json"]);
|
|
92
|
+
for (const groups of Object.values(config.hooks)) {
|
|
93
|
+
for (const group of groups) {
|
|
94
|
+
for (const hook of group.hooks) {
|
|
95
|
+
for (const arg of hook.args ?? []) {
|
|
96
|
+
if (typeof arg === "string" && arg.startsWith(prefix)) files.add(arg.slice(prefix.length));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
let valid = true;
|
|
102
|
+
for (const file of files) {
|
|
103
|
+
const destination = path.join(target, file);
|
|
104
|
+
if (!fs.existsSync(destination) || !fs.readFileSync(destination).equals(fs.readFileSync(path.join("cli", file)))) {
|
|
105
|
+
console.error(`::error::marketplace hook file missing or differs from source: ${file}`);
|
|
106
|
+
valid = false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
process.exitCode = valid ? 0 : 1;
|
|
110
|
+
JS
|
|
111
|
+
then
|
|
112
|
+
fail=1
|
|
113
|
+
fi
|
|
114
|
+
|
|
87
115
|
local marketplace_version claude_plugin_version codex_plugin_version skill_version
|
|
88
|
-
local skill_frontmatter_version
|
|
89
116
|
marketplace_version=$(node -p "require('$target/.claude-plugin/marketplace.json').plugins.find(p => p.name === 'graphit')?.version")
|
|
90
117
|
claude_plugin_version=$(node -p "require('$target/.claude-plugin/plugin.json').version")
|
|
91
118
|
codex_plugin_version=$(node -p "require('$target/.codex-plugin/plugin.json').version")
|
|
92
119
|
skill_version=$(node -p "require('$target/skills/graphit/VERSION.json').version")
|
|
93
|
-
skill_frontmatter_version=$(node -e "const fs=require('fs'); const m=fs.readFileSync('$target/skills/graphit/SKILL.md','utf8').match(/^skill_version:\\s*[\\\"']?([^\\\"'\\n]+)[\\\"']?\\s*$/m); console.log(m?.[1] ?? '')")
|
|
94
120
|
|
|
95
121
|
if [[ "$marketplace_version" != "$VERSION" ]]; then
|
|
96
122
|
echo "::error::marketplace.json graphit version ($marketplace_version) != package.json ($VERSION)"
|
|
@@ -108,8 +134,29 @@ verify_marketplace() {
|
|
|
108
134
|
echo "::error::skills/graphit/VERSION.json version ($skill_version) != package.json ($VERSION)"
|
|
109
135
|
fail=1
|
|
110
136
|
fi
|
|
111
|
-
|
|
112
|
-
|
|
137
|
+
local skill_path relative_path skill_frontmatter_version
|
|
138
|
+
for skill_path in cli/skills/*/SKILL.md; do
|
|
139
|
+
relative_path="${skill_path#cli/}"
|
|
140
|
+
if [[ ! -f "$target/$relative_path" ]]; then
|
|
141
|
+
echo "::error::marketplace missing $relative_path after sync"
|
|
142
|
+
fail=1
|
|
143
|
+
continue
|
|
144
|
+
fi
|
|
145
|
+
skill_frontmatter_version=$(node - "$target/$relative_path" <<'JS'
|
|
146
|
+
const fs = require("fs");
|
|
147
|
+
const text = fs.readFileSync(process.argv[2], "utf8");
|
|
148
|
+
const frontmatter = text.startsWith("---\n") ? text.split("\n---")[0] : "";
|
|
149
|
+
console.log(frontmatter.match(/^skill_version:\s*["']?([^"'\n]+)["']?\s*$/m)?.[1] ?? "");
|
|
150
|
+
JS
|
|
151
|
+
)
|
|
152
|
+
if [[ "$skill_frontmatter_version" != "$VERSION" ]]; then
|
|
153
|
+
echo "::error::$relative_path frontmatter version ($skill_frontmatter_version) != package.json ($VERSION)"
|
|
154
|
+
fail=1
|
|
155
|
+
fi
|
|
156
|
+
done
|
|
157
|
+
|
|
158
|
+
if ! diff -qr -x '.*' cli/skills "$target/skills"; then
|
|
159
|
+
echo "::error::marketplace skill content differs from the canonical skills tree"
|
|
113
160
|
fail=1
|
|
114
161
|
fi
|
|
115
162
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
@@ -122,7 +122,12 @@ updatePluginManifest(join(cliRoot, ".claude-plugin", "plugin.json"), version, ch
|
|
|
122
122
|
updatePluginManifest(join(cliRoot, ".codex-plugin", "plugin.json"), version, changes);
|
|
123
123
|
updateMarketplace(join(cliRoot, ".claude-plugin", "marketplace.json"), version, packageName, changes);
|
|
124
124
|
updateVersionJson(join(cliRoot, "skills", "graphit", "VERSION.json"), packageName, version, changes);
|
|
125
|
-
|
|
125
|
+
for (const entry of readdirSync(join(cliRoot, "skills"), { withFileTypes: true })) {
|
|
126
|
+
const skill = join(cliRoot, "skills", entry.name, "SKILL.md");
|
|
127
|
+
if (entry.isDirectory() && existsSync(skill)) {
|
|
128
|
+
updateSkillFile(skill, version, packageName, changes);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
126
131
|
// graphit.mdc is the frozen Cursor mirror and is no longer stamped (Cursor unmaintained for Claude Code + Codex).
|
|
127
132
|
updateWrapperFloor(join(cliRoot, "bin", "graphit"), version, changes);
|
|
128
133
|
updateWrapperFloor(join(cliRoot, "bin", "graphit.ps1"), version, changes);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Project #298: one authored workflow serves native host skills and the app loader.
|
|
3
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const root = process.env.GRAPHIT_CLI_ROOT ?? fileURLToPath(new URL("..", import.meta.url));
|
|
8
|
+
const check = process.argv.includes("--check");
|
|
9
|
+
const intents = ["explore", "build", "share"];
|
|
10
|
+
const pending = [];
|
|
11
|
+
|
|
12
|
+
function block(text, marker, source) {
|
|
13
|
+
const start = `<!-- ${marker}:START -->`;
|
|
14
|
+
const end = `<!-- ${marker}:END -->`;
|
|
15
|
+
const parts = text.split(start);
|
|
16
|
+
const tail = parts[1]?.split(end);
|
|
17
|
+
if (parts.length !== 2 || text.split(end).length !== 2 || tail?.length !== 2 || !tail[0].trim()) {
|
|
18
|
+
throw new Error(`${source}: expected one nonempty ${marker} block in order`);
|
|
19
|
+
}
|
|
20
|
+
return { body: tail[0].trim(), before: parts[0], after: tail[1], start, end };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function plan(destination, output) {
|
|
24
|
+
let current;
|
|
25
|
+
try {
|
|
26
|
+
current = readFileSync(join(root, destination), "utf8");
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (error.code !== "ENOENT") throw error;
|
|
29
|
+
}
|
|
30
|
+
if (current !== output) pending.push({ destination, output });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const core = "skills/graphit/SKILL.md";
|
|
34
|
+
const essentials = block(readFileSync(join(root, core), "utf8"), "GRAPHIT-ESSENTIALS", core).body;
|
|
35
|
+
|
|
36
|
+
for (const intent of intents) {
|
|
37
|
+
const source = `skills/graphit-${intent}/SKILL.md`;
|
|
38
|
+
const text = readFileSync(join(root, source), "utf8");
|
|
39
|
+
const name = text.match(/^name: (.+)$/m)?.[1];
|
|
40
|
+
const title = text.match(/^# .+$/m)?.[0];
|
|
41
|
+
const workflow = block(text, "WORKFLOW", source);
|
|
42
|
+
const shared = block(text, "GRAPHIT-ESSENTIALS", source);
|
|
43
|
+
if (name !== `graphit-${intent}` || !title || !shared.after.includes(workflow.start)) {
|
|
44
|
+
throw new Error(`${source}: expected matching name/title and essentials before workflow`);
|
|
45
|
+
}
|
|
46
|
+
plan(source, `${shared.before}${shared.start}\n${essentials}\n${shared.end}${shared.after}`);
|
|
47
|
+
const body = workflow.body
|
|
48
|
+
.replaceAll("../graphit/references/", "")
|
|
49
|
+
.replace(/\[graphit-(explore|build|share)\]\(\.\.\/graphit-\1\/SKILL\.md\)/g, "$1.md");
|
|
50
|
+
const output = `<!-- Generated from ${source}; edit the workflow skill, then run npm run sync:workflows. -->\n\n${title}\n\n${body}\n`;
|
|
51
|
+
plan(`skills/graphit/references/${intent}.md`, output);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Validate every source before any write, including when a later workflow is malformed.
|
|
55
|
+
if (check && pending.length) {
|
|
56
|
+
console.error(`Workflow artifacts out of sync: ${pending.map(item => item.destination).join(", ")}. Run npm run sync:workflows.`);
|
|
57
|
+
process.exitCode = 1;
|
|
58
|
+
} else {
|
|
59
|
+
for (const { destination, output } of pending) writeFileSync(join(root, destination), output);
|
|
60
|
+
console.log(pending.length ? `Synced ${pending.length} workflow artifacts.` : "Workflow artifacts are in sync.");
|
|
61
|
+
}
|
|
@@ -474,12 +474,12 @@
|
|
|
474
474
|
"silent_retry_exempt": true
|
|
475
475
|
},
|
|
476
476
|
"ds delete": {
|
|
477
|
-
"surface": "
|
|
477
|
+
"surface": "both",
|
|
478
478
|
"is_read_only": false,
|
|
479
479
|
"mutation_class": "data_source",
|
|
480
480
|
"requires_approval": true,
|
|
481
481
|
"silent_retry_exempt": true,
|
|
482
|
-
"reason": "
|
|
482
|
+
"reason": "Delete only the caller's own private sources through the same policy-complete route on both surfaces. Shared sources remain in the Sources Hub; applied cleanup-pending deletes must not be retried."
|
|
483
483
|
},
|
|
484
484
|
"ds move": {
|
|
485
485
|
"surface": "cli_only",
|
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
"mutation_class": "data_source",
|
|
488
488
|
"requires_approval": true,
|
|
489
489
|
"silent_retry_exempt": true,
|
|
490
|
-
"reason": "Not a working verb on either surface, and
|
|
490
|
+
"reason": "Not a working verb on either surface, and there is no UI action behind it (Issue #962). A source has no home of its own: it lives in the group of the semantic model bound to it, so `kb update semantic-model` with a new group is the move. The CLI registers `ds move` only to say so."
|
|
491
491
|
},
|
|
492
492
|
"dashboard folder spaces": {
|
|
493
493
|
"surface": "both", "noun": "dashboard", "is_read_only": true,
|