data-vizard 0.0.1 → 0.1.0
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/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +30 -0
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/bin/data-vizard.js +361 -1
- package/package.json +31 -10
- package/plugins/data-vizard/.claude-plugin/plugin.json +20 -0
- package/plugins/data-vizard/.codex-plugin/plugin.json +36 -0
- package/plugins/data-vizard/README.md +146 -0
- package/plugins/data-vizard/skills/data-analyst/SKILL.md +63 -0
- package/plugins/data-vizard/skills/data-analyst/agents/openai.yaml +4 -0
- package/plugins/data-vizard/skills/data-analyst/references/analysis-playbook.md +30 -0
- package/plugins/data-vizard/skills/data-curator/SKILL.md +67 -0
- package/plugins/data-vizard/skills/data-curator/agents/openai.yaml +4 -0
- package/plugins/data-vizard/skills/data-curator/references/dataset-intake-checklist.md +34 -0
- package/plugins/data-vizard/skills/data-vizard/SKILL.md +137 -0
- package/plugins/data-vizard/skills/data-vizard/agents/openai.yaml +4 -0
- package/plugins/data-vizard/skills/data-vizard/references/workflow-map.md +60 -0
- package/plugins/data-vizard/skills/designer/SKILL.md +107 -0
- package/plugins/data-vizard/skills/designer/agents/openai.yaml +4 -0
- package/plugins/data-vizard/skills/designer/assets/html-starter/index.html +95 -0
- package/plugins/data-vizard/skills/designer/references/style-directions.md +40 -0
- package/plugins/data-vizard/skills/narrator/SKILL.md +62 -0
- package/plugins/data-vizard/skills/narrator/agents/openai.yaml +4 -0
- package/plugins/data-vizard/skills/narrator/references/anti-ai-tropes.md +43 -0
- package/plugins/data-vizard/skills/narrator/references/story-structures.md +29 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "data-vizard",
|
|
3
|
+
"interface": {
|
|
4
|
+
"displayName": "Data Vizard"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "data-vizard",
|
|
9
|
+
"source": {
|
|
10
|
+
"source": "local",
|
|
11
|
+
"path": "./plugins/data-vizard"
|
|
12
|
+
},
|
|
13
|
+
"policy": {
|
|
14
|
+
"installation": "AVAILABLE",
|
|
15
|
+
"authentication": "ON_INSTALL"
|
|
16
|
+
},
|
|
17
|
+
"category": "Productivity"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "data-vizard",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Trine"
|
|
5
|
+
},
|
|
6
|
+
"description": "Data Vizard agent workflow plugins.",
|
|
7
|
+
"version": "0.1.0",
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "data-vizard",
|
|
11
|
+
"source": "./plugins/data-vizard",
|
|
12
|
+
"displayName": "Data Vizard",
|
|
13
|
+
"description": "Guide data visualization projects from dataset intake to analysis, narrative, design, and HTML story output.",
|
|
14
|
+
"version": "0.1.0",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Trine"
|
|
17
|
+
},
|
|
18
|
+
"repository": "https://github.com/inosaint/data-vizard",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"keywords": [
|
|
21
|
+
"data-visualization",
|
|
22
|
+
"storytelling",
|
|
23
|
+
"csv",
|
|
24
|
+
"analysis",
|
|
25
|
+
"html"
|
|
26
|
+
],
|
|
27
|
+
"category": "Productivity"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Trine
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Data Vizard
|
|
2
|
+
|
|
3
|
+
Data Vizard is a WIP agent plugin for building data visualization stories with a staged workflow. The workflow moves from data intake to analysis, narrative framing, visual design, and a final HTML artifact while keeping user decisions explicit.
|
|
4
|
+
|
|
5
|
+
## Workflow
|
|
6
|
+
|
|
7
|
+
Most projects follow this path:
|
|
8
|
+
|
|
9
|
+
1. `data-vizard` coordinates the project and decision gates.
|
|
10
|
+
2. `data-curator` finds, evaluates, cleans, joins, and documents data.
|
|
11
|
+
3. `data-analyst` explores the curated data and proposes evidence-backed story directions.
|
|
12
|
+
4. `narrator` turns the selected analytical direction into a story brief, copy, caveats, and annotation plan.
|
|
13
|
+
5. `designer` chooses the visual form with the user, then builds and verifies the HTML artifact.
|
|
14
|
+
|
|
15
|
+
Project folders use lowercase hyphen-case slugs, for example `nyc-taxi-weather-jan-2026`.
|
|
16
|
+
|
|
17
|
+
## Skills
|
|
18
|
+
|
|
19
|
+
The local skills live in `skills/`.
|
|
20
|
+
|
|
21
|
+
- `skills/data-vizard/` - Orchestrates the full visualization workflow, routes between role skills, and maintains decision gates.
|
|
22
|
+
- `skills/data-curator/` - Handles dataset discovery, data fitness checks, cleaning, reshaping, joins, enrichment, and curator handoff notes.
|
|
23
|
+
- `skills/data-analyst/` - Profiles curated datasets, finds patterns and caveats, and proposes possible story directions without choosing the final story silently.
|
|
24
|
+
- `skills/narrator/` - Shapes the selected analysis into audience-facing structure: story spine, titles, section copy, annotations, and caveats.
|
|
25
|
+
- `skills/designer/` - Designs and produces HTML-based visualization artifacts, including chart choice, layout, interaction, accessibility, visual style, and motion behavior.
|
|
26
|
+
|
|
27
|
+
Each skill has a `SKILL.md` file with its operating rules. Some skills also include `references/` for playbooks and reusable guidance, or `assets/` for starter files.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Install the published package with npm, pnpm, or Bun:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx data-vizard install
|
|
35
|
+
pnpm dlx data-vizard install
|
|
36
|
+
bunx data-vizard install
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The installer copies the bundled plugin into a stable local marketplace at `~/.data-vizard/marketplace`, then registers and installs it for Codex and Claude Code when their CLIs are available.
|
|
40
|
+
|
|
41
|
+
After installing, start a new agent session and invoke the orchestrator:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
Codex: $data-vizard:data-vizard
|
|
45
|
+
Claude Code: /data-vizard:data-vizard
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Manual Plugin Install
|
|
49
|
+
|
|
50
|
+
The plugin source lives in `plugins/data-vizard/`, with repo-local marketplace files for Codex and Claude Code. From a fresh clone, install it manually with:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
codex plugin marketplace add "$(pwd)"
|
|
54
|
+
codex plugin add data-vizard@data-vizard
|
|
55
|
+
|
|
56
|
+
claude plugin marketplace add "$(pwd)"
|
|
57
|
+
claude plugin install data-vizard@data-vizard
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
See `plugins/data-vizard/README.md` for full install, usage, update, and troubleshooting notes.
|
|
61
|
+
|
|
62
|
+
## Folder Guide
|
|
63
|
+
|
|
64
|
+
- `outcome/` - Final or in-progress public-facing visualization artifacts. Each project gets its own folder, usually with an `index.html` and supporting files such as story briefs, design notes, SVG favicons, or map assets.
|
|
65
|
+
- `data/` - Curated data, raw source snapshots, transformation notes, and intermediate datasets used to build a visualization.
|
|
66
|
+
- `scripts/` - Reproducible data preparation scripts. For example, `scripts/build_nyc_taxi_weather_hourly.py` builds the NYC taxi/weather dataset.
|
|
67
|
+
- `skills/` - Local role skills used by the Data Vizard workflow.
|
|
68
|
+
- `project-ledgers/` - Project ledgers that record stage progress, skill handoffs, decisions, caveats, and important files.
|
|
69
|
+
- `outcome/<project-name>/PRODUCT.md` - Project-specific product context: audience, purpose, brand personality, anti-references, design principles, and accessibility goals.
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
## Current Projects
|
|
73
|
+
|
|
74
|
+
- `outcome/nyc-taxi-weather-jan-2026/` - A map-led scrollytelling story about how the January 25, 2026 snow day affected NYC yellow taxi pickups.
|
|
75
|
+
- `outcome/india-state-choropleth/` - An India state choropleth visualization workspace.
|
|
76
|
+
|
|
77
|
+
## Working Notes
|
|
78
|
+
|
|
79
|
+
- Keep user-facing visualization outputs under `outcome/<project-name>/`.
|
|
80
|
+
- Keep curated data and transformation artifacts under `data/<project-name>/`.
|
|
81
|
+
- Keep project progress notes in `project-ledgers/<project-name>.md`.
|
|
82
|
+
- When adding new skills, include a clear `SKILL.md` and keep supporting guidance in that skill's `references/` folder.
|
|
83
|
+
- For chart and map animations, prefer semantic data transitions: animate heights, bases, segment boundaries, filters, and scales rather than relying on opacity-only color swaps.
|
package/bin/data-vizard.js
CHANGED
|
@@ -1,2 +1,362 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const os = require("node:os");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
const { spawnSync } = require("node:child_process");
|
|
7
|
+
|
|
8
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
9
|
+
const PLUGIN_NAME = "data-vizard";
|
|
10
|
+
const MARKETPLACE_NAME = "data-vizard";
|
|
11
|
+
const DISPLAY_NAME = "Data Vizard";
|
|
12
|
+
|
|
13
|
+
function main() {
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0];
|
|
16
|
+
|
|
17
|
+
if (!command || command === "--help" || command === "-h") {
|
|
18
|
+
printHelp();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (command === "--version" || command === "-v") {
|
|
23
|
+
console.log(readPackageJson().version);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (command === "install") {
|
|
28
|
+
install(args.slice(1));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.error(`Unknown command: ${command}`);
|
|
33
|
+
printHelp();
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function printHelp() {
|
|
38
|
+
console.log(`Data Vizard
|
|
39
|
+
|
|
40
|
+
Usage:
|
|
41
|
+
data-vizard install [options]
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
--root <path> Stable marketplace root to write. Default: ~/.data-vizard/marketplace
|
|
45
|
+
--no-codex Stage files but skip Codex CLI registration/install.
|
|
46
|
+
--no-claude Stage files but skip Claude Code CLI registration/install.
|
|
47
|
+
--dry-run Print planned actions without writing files or running CLIs.
|
|
48
|
+
-h, --help Show this help.
|
|
49
|
+
-v, --version Show package version.
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function install(args) {
|
|
54
|
+
const options = parseInstallOptions(args);
|
|
55
|
+
const packageJson = readPackageJson();
|
|
56
|
+
const marketplaceRoot = path.resolve(
|
|
57
|
+
expandHome(options.root || path.join(os.homedir(), ".data-vizard", "marketplace")),
|
|
58
|
+
);
|
|
59
|
+
const sourcePluginDir = path.join(PACKAGE_ROOT, "plugins", PLUGIN_NAME);
|
|
60
|
+
const targetPluginDir = path.join(marketplaceRoot, "plugins", PLUGIN_NAME);
|
|
61
|
+
|
|
62
|
+
if (!fs.existsSync(sourcePluginDir)) {
|
|
63
|
+
throw new Error(`Bundled plugin not found at ${sourcePluginDir}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const codexMarketplacePath = path.join(marketplaceRoot, ".agents", "plugins", "marketplace.json");
|
|
67
|
+
const claudeMarketplacePath = path.join(marketplaceRoot, ".claude-plugin", "marketplace.json");
|
|
68
|
+
|
|
69
|
+
console.log(`${DISPLAY_NAME} installer ${packageJson.version}`);
|
|
70
|
+
console.log(`Marketplace root: ${marketplaceRoot}`);
|
|
71
|
+
|
|
72
|
+
if (options.dryRun) {
|
|
73
|
+
console.log(`Would copy ${sourcePluginDir} -> ${targetPluginDir}`);
|
|
74
|
+
console.log(`Would write ${codexMarketplacePath}`);
|
|
75
|
+
console.log(`Would write ${claudeMarketplacePath}`);
|
|
76
|
+
} else {
|
|
77
|
+
copyPlugin(sourcePluginDir, targetPluginDir);
|
|
78
|
+
writeJson(codexMarketplacePath, createCodexMarketplace());
|
|
79
|
+
writeJson(claudeMarketplacePath, createClaudeMarketplace(packageJson.version));
|
|
80
|
+
console.log("Staged Data Vizard marketplace files.");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const stagedOnly = options.noCodex && options.noClaude;
|
|
84
|
+
if (!options.noCodex) {
|
|
85
|
+
installCodex(marketplaceRoot, options.dryRun);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!options.noClaude) {
|
|
89
|
+
installClaude(marketplaceRoot, options.dryRun);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (stagedOnly) {
|
|
93
|
+
printManualCommands(marketplaceRoot);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log("");
|
|
97
|
+
console.log("Start a new Codex thread and use $data-vizard:data-vizard.");
|
|
98
|
+
console.log("Start a new Claude Code session and use /data-vizard:data-vizard.");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function parseInstallOptions(args) {
|
|
102
|
+
const options = {
|
|
103
|
+
root: null,
|
|
104
|
+
noCodex: false,
|
|
105
|
+
noClaude: false,
|
|
106
|
+
dryRun: false,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
110
|
+
const arg = args[index];
|
|
111
|
+
|
|
112
|
+
if (arg === "--root") {
|
|
113
|
+
const value = args[index + 1];
|
|
114
|
+
if (!value) {
|
|
115
|
+
throw new Error("--root requires a path");
|
|
116
|
+
}
|
|
117
|
+
options.root = value;
|
|
118
|
+
index += 1;
|
|
119
|
+
} else if (arg === "--no-codex") {
|
|
120
|
+
options.noCodex = true;
|
|
121
|
+
} else if (arg === "--no-claude") {
|
|
122
|
+
options.noClaude = true;
|
|
123
|
+
} else if (arg === "--dry-run") {
|
|
124
|
+
options.dryRun = true;
|
|
125
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
126
|
+
printHelp();
|
|
127
|
+
process.exit(0);
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error(`Unknown install option: ${arg}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return options;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function copyPlugin(sourcePluginDir, targetPluginDir) {
|
|
137
|
+
fs.rmSync(targetPluginDir, { recursive: true, force: true });
|
|
138
|
+
fs.mkdirSync(path.dirname(targetPluginDir), { recursive: true });
|
|
139
|
+
fs.cpSync(sourcePluginDir, targetPluginDir, {
|
|
140
|
+
recursive: true,
|
|
141
|
+
dereference: true,
|
|
142
|
+
filter: (source) => !source.includes(`${path.sep}.DS_Store`),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function createCodexMarketplace() {
|
|
147
|
+
return {
|
|
148
|
+
name: MARKETPLACE_NAME,
|
|
149
|
+
interface: {
|
|
150
|
+
displayName: DISPLAY_NAME,
|
|
151
|
+
},
|
|
152
|
+
plugins: [
|
|
153
|
+
{
|
|
154
|
+
name: PLUGIN_NAME,
|
|
155
|
+
source: {
|
|
156
|
+
source: "local",
|
|
157
|
+
path: `./plugins/${PLUGIN_NAME}`,
|
|
158
|
+
},
|
|
159
|
+
policy: {
|
|
160
|
+
installation: "AVAILABLE",
|
|
161
|
+
authentication: "ON_INSTALL",
|
|
162
|
+
},
|
|
163
|
+
category: "Productivity",
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function createClaudeMarketplace(version) {
|
|
170
|
+
return {
|
|
171
|
+
name: MARKETPLACE_NAME,
|
|
172
|
+
owner: {
|
|
173
|
+
name: "Trine",
|
|
174
|
+
},
|
|
175
|
+
description: "Data Vizard agent workflow plugins.",
|
|
176
|
+
version,
|
|
177
|
+
plugins: [
|
|
178
|
+
{
|
|
179
|
+
name: PLUGIN_NAME,
|
|
180
|
+
source: `./plugins/${PLUGIN_NAME}`,
|
|
181
|
+
displayName: DISPLAY_NAME,
|
|
182
|
+
description:
|
|
183
|
+
"Guide data visualization projects from dataset intake to analysis, narrative, design, and HTML story output.",
|
|
184
|
+
version,
|
|
185
|
+
author: {
|
|
186
|
+
name: "Trine",
|
|
187
|
+
},
|
|
188
|
+
repository: "https://github.com/inosaint/data-vizard",
|
|
189
|
+
license: "MIT",
|
|
190
|
+
keywords: ["data-visualization", "storytelling", "csv", "analysis", "html"],
|
|
191
|
+
category: "Productivity",
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function installCodex(marketplaceRoot, dryRun) {
|
|
198
|
+
console.log("");
|
|
199
|
+
console.log("Codex");
|
|
200
|
+
|
|
201
|
+
const addArgs = ["plugin", "marketplace", "add", marketplaceRoot];
|
|
202
|
+
const installArgs = ["plugin", "add", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`];
|
|
203
|
+
|
|
204
|
+
if (dryRun) {
|
|
205
|
+
console.log(`Would run: codex ${addArgs.map(shellQuote).join(" ")}`);
|
|
206
|
+
console.log(`Would run: codex ${installArgs.join(" ")}`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!commandExists("codex")) {
|
|
211
|
+
console.log("Codex CLI was not found on PATH.");
|
|
212
|
+
printCodexCommands(marketplaceRoot);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const add = run("codex", addArgs);
|
|
217
|
+
if (!add.ok) {
|
|
218
|
+
console.warn("Could not register the Codex marketplace automatically.");
|
|
219
|
+
printCommandOutput(add);
|
|
220
|
+
console.warn("Continuing in case the marketplace was already registered.");
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const pluginInstall = run("codex", installArgs);
|
|
224
|
+
if (pluginInstall.ok) {
|
|
225
|
+
console.log("Installed data-vizard@data-vizard in Codex.");
|
|
226
|
+
} else {
|
|
227
|
+
console.warn("Could not install the Codex plugin automatically.");
|
|
228
|
+
printCommandOutput(pluginInstall);
|
|
229
|
+
printCodexCommands(marketplaceRoot);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function installClaude(marketplaceRoot, dryRun) {
|
|
234
|
+
console.log("");
|
|
235
|
+
console.log("Claude Code");
|
|
236
|
+
|
|
237
|
+
const marketplaceArgs = ["plugin", "marketplace", "add", marketplaceRoot];
|
|
238
|
+
const installArgs = ["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`];
|
|
239
|
+
|
|
240
|
+
if (dryRun) {
|
|
241
|
+
console.log(`Would run: claude ${marketplaceArgs.map(shellQuote).join(" ")}`);
|
|
242
|
+
console.log(`Would run: claude ${installArgs.join(" ")}`);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (!commandExists("claude")) {
|
|
247
|
+
console.log("Claude Code CLI was not found on PATH.");
|
|
248
|
+
printClaudeCommands(marketplaceRoot);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const add = run("claude", marketplaceArgs);
|
|
253
|
+
if (!add.ok) {
|
|
254
|
+
console.warn("Could not register the Claude Code marketplace automatically.");
|
|
255
|
+
printCommandOutput(add);
|
|
256
|
+
console.warn("Continuing in case the marketplace was already registered.");
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const pluginInstall = run("claude", installArgs);
|
|
260
|
+
if (pluginInstall.ok) {
|
|
261
|
+
console.log("Installed data-vizard@data-vizard in Claude Code.");
|
|
262
|
+
} else {
|
|
263
|
+
console.warn("Could not install the Claude Code plugin automatically.");
|
|
264
|
+
printCommandOutput(pluginInstall);
|
|
265
|
+
printClaudeCommands(marketplaceRoot);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function printManualCommands(marketplaceRoot) {
|
|
270
|
+
printCodexCommands(marketplaceRoot);
|
|
271
|
+
printClaudeCommands(marketplaceRoot);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function printCodexCommands(marketplaceRoot) {
|
|
275
|
+
console.log("");
|
|
276
|
+
console.log("To finish Codex installation manually:");
|
|
277
|
+
console.log(` codex plugin marketplace add ${shellQuote(marketplaceRoot)}`);
|
|
278
|
+
console.log(` codex plugin add ${PLUGIN_NAME}@${MARKETPLACE_NAME}`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function printClaudeCommands(marketplaceRoot) {
|
|
282
|
+
console.log("");
|
|
283
|
+
console.log("To finish Claude Code installation manually:");
|
|
284
|
+
console.log(` claude plugin marketplace add ${shellQuote(marketplaceRoot)}`);
|
|
285
|
+
console.log(` claude plugin install ${PLUGIN_NAME}@${MARKETPLACE_NAME}`);
|
|
286
|
+
console.log("");
|
|
287
|
+
console.log("Or inside an interactive Claude Code session:");
|
|
288
|
+
console.log(` /plugin marketplace add ${marketplaceRoot}`);
|
|
289
|
+
console.log(` /plugin install ${PLUGIN_NAME}@${MARKETPLACE_NAME}`);
|
|
290
|
+
console.log(" /reload-plugins");
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function commandExists(command) {
|
|
294
|
+
const result = spawnSync(command, ["--version"], { encoding: "utf8" });
|
|
295
|
+
return !(result.error && result.error.code === "ENOENT");
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function run(command, args) {
|
|
299
|
+
const result = spawnSync(command, args, { encoding: "utf8" });
|
|
300
|
+
return {
|
|
301
|
+
ok: !result.error && result.status === 0,
|
|
302
|
+
status: result.status,
|
|
303
|
+
error: result.error,
|
|
304
|
+
stdout: result.stdout,
|
|
305
|
+
stderr: result.stderr,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function printCommandOutput(result) {
|
|
310
|
+
if (result.error) {
|
|
311
|
+
console.warn(` ${result.error.message}`);
|
|
312
|
+
}
|
|
313
|
+
if (result.stderr && result.stderr.trim()) {
|
|
314
|
+
console.warn(indent(result.stderr.trim()));
|
|
315
|
+
}
|
|
316
|
+
if (result.stdout && result.stdout.trim()) {
|
|
317
|
+
console.warn(indent(result.stdout.trim()));
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function writeJson(filePath, value) {
|
|
322
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
323
|
+
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function readPackageJson() {
|
|
327
|
+
return JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8"));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function expandHome(inputPath) {
|
|
331
|
+
if (inputPath === "~") {
|
|
332
|
+
return os.homedir();
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (inputPath.startsWith(`~${path.sep}`)) {
|
|
336
|
+
return path.join(os.homedir(), inputPath.slice(2));
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return inputPath;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function shellQuote(value) {
|
|
343
|
+
if (/^[A-Za-z0-9_./:@%+=,-]+$/.test(value)) {
|
|
344
|
+
return value;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function indent(value) {
|
|
351
|
+
return value
|
|
352
|
+
.split("\n")
|
|
353
|
+
.map((line) => ` ${line}`)
|
|
354
|
+
.join("\n");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
try {
|
|
358
|
+
main();
|
|
359
|
+
} catch (error) {
|
|
360
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
361
|
+
process.exitCode = 1;
|
|
362
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-vizard",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Data Vizard
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Installer for the Data Vizard agent workflow plugin.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Trine"
|
|
8
8
|
},
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
"homepage": "https://github.com/inosaint/data-vizard#readme",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/inosaint/data-vizard.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/inosaint/data-vizard/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"agent-skills",
|
|
19
|
+
"claude-code",
|
|
20
|
+
"codex",
|
|
21
|
+
"data-visualization",
|
|
22
|
+
"plugin"
|
|
23
|
+
],
|
|
13
24
|
"bin": {
|
|
14
|
-
"data-vizard": "
|
|
25
|
+
"data-vizard": "bin/data-vizard.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"bin/",
|
|
29
|
+
"plugins/data-vizard/",
|
|
30
|
+
".agents/plugins/marketplace.json",
|
|
31
|
+
".claude-plugin/marketplace.json",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18"
|
|
15
36
|
}
|
|
16
37
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "data-vizard",
|
|
3
|
+
"displayName": "Data Vizard",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Guide data visualization projects from dataset intake to analysis, narrative, design, and HTML story output.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Trine",
|
|
8
|
+
"url": "https://github.com/inosaint"
|
|
9
|
+
},
|
|
10
|
+
"repository": "https://github.com/inosaint/data-vizard",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"data-visualization",
|
|
14
|
+
"storytelling",
|
|
15
|
+
"csv",
|
|
16
|
+
"analysis",
|
|
17
|
+
"html"
|
|
18
|
+
],
|
|
19
|
+
"skills": "./skills/"
|
|
20
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "data-vizard",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A staged data visualization workshop for moving from dataset intake to analysis, narrative, design, and an HTML artifact.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Trine"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"data-visualization",
|
|
11
|
+
"storytelling",
|
|
12
|
+
"csv",
|
|
13
|
+
"analysis",
|
|
14
|
+
"html"
|
|
15
|
+
],
|
|
16
|
+
"skills": "./skills/",
|
|
17
|
+
"interface": {
|
|
18
|
+
"displayName": "Data Vizard",
|
|
19
|
+
"shortDescription": "Guide data visualization projects from dataset to HTML story.",
|
|
20
|
+
"longDescription": "Data Vizard bundles five Codex skills for a complete data visualization workflow: orchestration, data curation, exploratory analysis, narrative framing, and HTML visualization design.",
|
|
21
|
+
"developerName": "Trine",
|
|
22
|
+
"category": "Productivity",
|
|
23
|
+
"capabilities": [
|
|
24
|
+
"Interactive",
|
|
25
|
+
"Write",
|
|
26
|
+
"Data Analysis",
|
|
27
|
+
"Visualization"
|
|
28
|
+
],
|
|
29
|
+
"brandColor": "#2563EB",
|
|
30
|
+
"defaultPrompt": [
|
|
31
|
+
"Use Data Vizard to build a visualization from this CSV.",
|
|
32
|
+
"Guide me from dataset intake to an HTML data story.",
|
|
33
|
+
"Help me choose the best story direction for this dataset."
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|