@ggterm/core 0.3.2 → 0.3.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/dist/cli-plot.js CHANGED
@@ -14693,6 +14693,15 @@ function handleServe(port) {
14693
14693
  res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
14694
14694
  res.end(CLIENT_HTML);
14695
14695
  });
14696
+ server.on("error", (err) => {
14697
+ if (err.code === "EADDRINUSE") {
14698
+ console.error(`Port ${p} is already in use.`);
14699
+ console.error(`Kill the existing server: lsof -ti:${p} | xargs kill`);
14700
+ console.error(`Or use a different port: npx ggterm-plot serve ${p + 1}`);
14701
+ process.exit(1);
14702
+ }
14703
+ throw err;
14704
+ });
14696
14705
  server.listen(p, () => {
14697
14706
  const url = `http://localhost:${p}`;
14698
14707
  console.log(`ggterm live viewer running at ${url}`);
@@ -15183,7 +15192,7 @@ import { join as join4 } from "path";
15183
15192
  // src/init.ts
15184
15193
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync2, existsSync as existsSync2, readdirSync as readdirSync2, statSync } from "fs";
15185
15194
  import { join as join2, extname } from "path";
15186
- var SKILLS_VERSION = "0.2.7";
15195
+ var SKILLS_VERSION = "0.3.2";
15187
15196
  var SKILLS = {
15188
15197
  "data-load": {
15189
15198
  files: {
@@ -15197,73 +15206,41 @@ allowed-tools: Bash(npx:*), Read, Write
15197
15206
 
15198
15207
  Load data into arrays of records for use with ggterm plotting and analysis.
15199
15208
 
15200
- ## Quick Patterns by Format
15201
-
15202
- ### CSV
15203
-
15204
- \`\`\`typescript
15205
- import { parse } from 'csv-parse/sync'
15206
- import { readFileSync } from 'fs'
15209
+ ## Built-in Datasets (No files needed!)
15207
15210
 
15208
- const text = readFileSync('data.csv', 'utf-8')
15209
- const data = parse(text, {
15210
- columns: true, // First row as headers
15211
- cast: true, // Auto-convert numbers
15212
- skip_empty_lines: true
15213
- })
15214
- \`\`\`
15211
+ ggterm includes built-in datasets that can be used directly by name:
15215
15212
 
15216
- **Alternative with d3-dsv** (lighter weight):
15213
+ | Dataset | Rows | Columns |
15214
+ |---------|------|---------|
15215
+ | \`iris\` | 150 | sepal_length, sepal_width, petal_length, petal_width, species |
15216
+ | \`mtcars\` | 16 | mpg, cyl, hp, wt, name |
15217
15217
 
15218
- \`\`\`typescript
15219
- import { csvParse, autoType } from 'd3-dsv'
15218
+ Use them directly in plot commands:
15220
15219
 
15221
- const data = csvParse(readFileSync('data.csv', 'utf-8'), autoType)
15220
+ \`\`\`bash
15221
+ npx ggterm-plot iris sepal_length sepal_width species "Iris Dataset" point
15222
+ npx ggterm-plot mtcars mpg hp cyl "Motor Trend Cars" point
15222
15223
  \`\`\`
15223
15224
 
15224
- ### JSON
15225
-
15226
- \`\`\`typescript
15227
- import { readFileSync } from 'fs'
15228
-
15229
- // JSON array
15230
- const data = JSON.parse(readFileSync('data.json', 'utf-8'))
15231
- \`\`\`
15225
+ **IMPORTANT**: When the user asks about iris, mtcars, or bundled/built-in datasets, use these names directly with \`npx ggterm-plot\`. Do NOT try to generate CSV files or install Python packages.
15232
15226
 
15233
- ### JSONL (Newline-delimited JSON)
15227
+ ## External Files
15234
15228
 
15235
- \`\`\`typescript
15236
- const data = readFileSync('data.jsonl', 'utf-8')
15237
- .trim()
15238
- .split('\\n')
15239
- .map(line => JSON.parse(line))
15229
+ \`\`\`bash
15230
+ npx ggterm-plot data.csv x_column y_column color_column "Title" point
15231
+ npx ggterm-plot data.json x_column y_column
15232
+ npx ggterm-plot data.jsonl x_column y_column
15240
15233
  \`\`\`
15241
15234
 
15242
15235
  ## Verification
15243
15236
 
15244
- After loading, always verify the data structure:
15237
+ Inspect any data file to see columns and types:
15245
15238
 
15246
- \`\`\`typescript
15247
- console.log(\`Loaded \${data.length} rows\`)
15248
- console.log('Columns:', Object.keys(data[0]))
15249
- console.log('Sample row:', data[0])
15239
+ \`\`\`bash
15240
+ npx ggterm-plot inspect data.csv
15250
15241
  \`\`\`
15251
15242
 
15252
- ## Integration with ggterm
15253
-
15254
- Once data is loaded, pass directly to ggterm:
15255
-
15256
- \`\`\`typescript
15257
- import { gg, geom_point } from '@ggterm/core'
15258
-
15259
- const data = loadData('measurements.csv')
15260
-
15261
- const plot = gg(data)
15262
- .aes({ x: 'time', y: 'value' })
15263
- .geom(geom_point())
15264
-
15265
- console.log(plot.render({ width: 80, height: 24 }))
15266
- \`\`\`
15243
+ $ARGUMENTS
15267
15244
  `
15268
15245
  }
15269
15246
  },
@@ -15277,62 +15254,77 @@ allowed-tools: Bash(npx:ggterm-plot*), Read
15277
15254
 
15278
15255
  # Terminal Plotting with ggterm
15279
15256
 
15280
- Create plots using the CLI tool. Start by inspecting the data, then plot.
15257
+ Create plots using the CLI tool. Supports both built-in datasets and external files.
15258
+
15259
+ ## Built-in Datasets
15281
15260
 
15282
- ## Step 1: Inspect Data (Recommended)
15261
+ ggterm includes datasets that work by name — no CSV files needed:
15262
+
15263
+ | Dataset | Rows | Columns |
15264
+ |---------|------|---------|
15265
+ | \`iris\` | 150 | sepal_length, sepal_width, petal_length, petal_width, species |
15266
+ | \`mtcars\` | 16 | mpg, cyl, hp, wt, name |
15283
15267
 
15284
15268
  \`\`\`bash
15285
- npx ggterm-plot inspect <data.csv>
15269
+ npx ggterm-plot iris sepal_length sepal_width species "Iris" point
15270
+ npx ggterm-plot mtcars mpg hp cyl "Cars" point
15286
15271
  \`\`\`
15287
15272
 
15288
- Shows column names, types (numeric/categorical/date), unique counts, and sample values.
15273
+ **IMPORTANT**: When the user mentions iris, mtcars, or asks for demo/sample data, use these built-in names directly. Do NOT look for CSV files or generate data.
15274
+
15275
+ ## Live Plot Viewer
15289
15276
 
15290
- ## Step 2: Get Suggestions (Optional)
15277
+ Start the companion viewer for high-resolution interactive plots:
15291
15278
 
15292
15279
  \`\`\`bash
15293
- npx ggterm-plot suggest <data.csv>
15280
+ npx ggterm-plot serve # default port 4242
15281
+ npx ggterm-plot serve 8080 # custom port
15294
15282
  \`\`\`
15295
15283
 
15296
- Returns ready-to-run plot commands based on column types.
15284
+ When serve is running, plots auto-display in the browser/Wave panel instead of ASCII art.
15297
15285
 
15298
- ## Step 3: Create Plot
15286
+ ## CLI Command
15299
15287
 
15300
15288
  \`\`\`bash
15301
- npx ggterm-plot <data.csv> <x> <y> [color] [title] [geom]
15289
+ npx ggterm-plot <data> <x> <y> [color] [title] [geom]
15302
15290
  \`\`\`
15303
15291
 
15304
15292
  Arguments:
15305
- - \`data.csv\` - Path to CSV file
15293
+ - \`data\` - Built-in dataset name (\`iris\`, \`mtcars\`) OR path to CSV/JSON/JSONL file
15306
15294
  - \`x\` - Column name for x-axis
15307
15295
  - \`y\` - Column name for y-axis (use \`-\` for histogram)
15308
15296
  - \`color\` - Column name for color (optional, use \`-\` to skip)
15309
15297
  - \`title\` - Plot title (optional, use \`-\` to skip)
15310
- - \`geom\` - Geometry type: \`point\` (default), \`line\`, \`histogram\`, \`boxplot\`, \`bar\`, \`violin\`, \`area\`, etc.
15298
+ - \`geom\` - Geometry type: \`point\` (default), \`line\`, \`histogram\`, \`boxplot\`, \`bar\`, \`violin\`, \`density\`, \`area\`, etc.
15311
15299
 
15312
- ## Examples
15300
+ ## Inspect & Suggest (for external files)
15313
15301
 
15314
- Scatter plot:
15315
15302
  \`\`\`bash
15316
- npx ggterm-plot data.csv sepal_length sepal_width species "Iris Dataset" point
15303
+ npx ggterm-plot inspect <data.csv>
15304
+ npx ggterm-plot suggest <data.csv>
15317
15305
  \`\`\`
15318
15306
 
15319
- Histogram:
15307
+ ## Examples
15308
+
15309
+ Built-in data:
15320
15310
  \`\`\`bash
15321
- npx ggterm-plot data.csv sepal_width - - "Sepal Width Distribution" histogram
15311
+ npx ggterm-plot iris sepal_length sepal_width species "Iris Dataset" point
15312
+ npx ggterm-plot iris petal_length - species "Petal Length" histogram
15313
+ npx ggterm-plot mtcars mpg hp cyl "MPG vs HP" point
15322
15314
  \`\`\`
15323
15315
 
15324
- Box plot:
15316
+ External files:
15325
15317
  \`\`\`bash
15326
- npx ggterm-plot data.csv treatment response_time - "Response by Treatment" boxplot
15318
+ npx ggterm-plot data.csv x y color "Title" point
15319
+ npx ggterm-plot data.json date value - "Time Series" line
15327
15320
  \`\`\`
15328
15321
 
15329
15322
  ## Workflow
15330
15323
 
15331
- 1. Identify the data file from $ARGUMENTS or ask user
15332
- 2. Run \`inspect\` to see column names and types
15333
- 3. Run \`suggest\` to get recommended visualizations (or choose based on user request)
15334
- 4. Run the plot command
15335
- 5. Briefly describe what the plot shows
15324
+ 1. If user asks for iris/mtcars/demo data, use built-in dataset names directly
15325
+ 2. For external files: run \`inspect\` to see columns, then \`suggest\` for recommendations
15326
+ 3. Run the plot command
15327
+ 4. Briefly describe what the plot shows
15336
15328
 
15337
15329
  $ARGUMENTS
15338
15330
 
@@ -15345,6 +15337,11 @@ $ARGUMENTS
15345
15337
  | Distribution of 1 variable | \`histogram\` | Frequency distribution |
15346
15338
  | Distribution by group | \`boxplot\` | Compare medians |
15347
15339
  | Category comparison | \`bar\` | Counts per category |
15340
+ | Smoothed distribution | \`density\` | Kernel density estimate |
15341
+ | Density shape | \`violin\` | Distribution shape |
15342
+ | Stacked distributions | \`ridgeline\` | Joy plot |
15343
+ | Filled region | \`area\` | Cumulative or stacked |
15344
+ | Cumulative distribution | \`ecdf\` | Empirical CDF |
15348
15345
  `
15349
15346
  }
15350
15347
  },
@@ -15465,7 +15462,7 @@ $ARGUMENTS
15465
15462
  "SKILL.md": `---
15466
15463
  name: ggterm-customize
15467
15464
  description: Customize plot aesthetics using natural language. Use when the user wants to change colors, fonts, titles, labels, themes, or any visual aspect of a plot before publication.
15468
- allowed-tools: Read, Write
15465
+ allowed-tools: Read, Write, Bash(npx:*)
15469
15466
  ---
15470
15467
 
15471
15468
  # Natural Language Plot Customization
@@ -15522,7 +15519,7 @@ $ARGUMENTS
15522
15519
  "SKILL.md": `---
15523
15520
  name: ggterm-style
15524
15521
  description: Apply publication-quality style presets to plots. Use when the user wants to style a plot like Wilke, Tufte, Nature, The Economist, or apply minimal/publication styling.
15525
- allowed-tools: Read, Write
15522
+ allowed-tools: Read, Write, Bash(npx:*)
15526
15523
  ---
15527
15524
 
15528
15525
  # Plot Style Presets
@@ -15547,47 +15544,6 @@ Apply expert-curated style presets to Vega-Lite specifications for publication-q
15547
15544
  3. Write the updated spec
15548
15545
  4. Inform user they can export with \`/ggterm-publish\`
15549
15546
 
15550
- ## Style Configurations
15551
-
15552
- ### Wilke Style (Recommended Default)
15553
-
15554
- \`\`\`javascript
15555
- const wilkeStyle = {
15556
- config: {
15557
- font: "Helvetica Neue, Helvetica, Arial, sans-serif",
15558
- background: "white",
15559
- view: { stroke: null },
15560
- title: { fontSize: 14, fontWeight: "normal", anchor: "start" },
15561
- axis: { grid: false, labelFontSize: 11, titleFontSize: 12 },
15562
- axisY: { grid: true, gridColor: "#ebebeb" }
15563
- }
15564
- }
15565
- \`\`\`
15566
-
15567
- ### Tufte Style
15568
-
15569
- \`\`\`javascript
15570
- const tufteStyle = {
15571
- config: {
15572
- font: "Georgia, serif",
15573
- view: { stroke: null },
15574
- axis: { domain: false, grid: false, ticks: false }
15575
- }
15576
- }
15577
- \`\`\`
15578
-
15579
- ### Economist Style
15580
-
15581
- \`\`\`javascript
15582
- const economistStyle = {
15583
- config: {
15584
- background: "#d5e4eb",
15585
- axis: { grid: true, gridColor: "#ffffff" },
15586
- axisX: { grid: false, domain: true }
15587
- }
15588
- }
15589
- \`\`\`
15590
-
15591
15547
  ## Response Format
15592
15548
 
15593
15549
  After applying a style:
@@ -15624,18 +15580,6 @@ Generate analysis reports with embedded terminal visualizations.
15624
15580
  3. **Visualizations** - Embedded plots with interpretations
15625
15581
  4. **Findings** - Key insights from the analysis
15626
15582
 
15627
- ## Embedding Plots
15628
-
15629
- \`\`\`markdown
15630
- ## Visualization
15631
-
15632
- \\\`\\\`\\\`
15633
- [terminal plot output here]
15634
- \\\`\\\`\\\`
15635
-
15636
- **Interpretation**: The scatter plot shows [describe the relationship observed].
15637
- \`\`\`
15638
-
15639
15583
  ## Width Guidelines
15640
15584
 
15641
15585
  | Context | Width | Height |
@@ -15765,6 +15709,63 @@ function handleInit() {
15765
15709
  console.log(`ggterm v${SKILLS_VERSION} ready`);
15766
15710
  console.log("");
15767
15711
  }
15712
+ const claudeMdPath = join2(cwd, "CLAUDE.md");
15713
+ const claudeMdContent = `# ggterm Data Analysis Project
15714
+
15715
+ This project uses ggterm (@ggterm/core) for data visualization.
15716
+
15717
+ ## IMPORTANT: Built-in Datasets
15718
+
15719
+ ggterm has built-in datasets that work by name — NO CSV files or Python packages needed:
15720
+
15721
+ \`\`\`bash
15722
+ npx ggterm-plot iris sepal_length sepal_width species "Iris" point
15723
+ npx ggterm-plot mtcars mpg hp cyl "Cars" point
15724
+ \`\`\`
15725
+
15726
+ | Dataset | Rows | Columns |
15727
+ |---------|------|---------|
15728
+ | \`iris\` | 150 | sepal_length, sepal_width, petal_length, petal_width, species |
15729
+ | \`mtcars\` | 16 | mpg, cyl, hp, wt, name |
15730
+
15731
+ When asked about iris, mtcars, or sample data, use these names directly as the first argument to \`npx ggterm-plot\`. Do NOT search for CSV files or generate data.
15732
+
15733
+ ## Plotting Commands
15734
+
15735
+ \`\`\`bash
15736
+ npx ggterm-plot <data> <x> <y> [color] [title] [geom]
15737
+ npx ggterm-plot serve # Start live viewer (port 4242)
15738
+ npx ggterm-plot inspect <file> # Show column types
15739
+ npx ggterm-plot suggest <file> # Suggest visualizations
15740
+ npx ggterm-plot history # List previous plots
15741
+ npx ggterm-plot export <id> out.html # Export plot
15742
+ \`\`\`
15743
+
15744
+ ## Geom Types
15745
+
15746
+ point, line, histogram, boxplot, bar, violin, density, area, ridgeline, heatmap, scatter, ecdf, smooth, and 50+ more.
15747
+
15748
+ ## Live Viewer
15749
+
15750
+ When \`npx ggterm-plot serve\` is running, plots auto-display in the browser/Wave panel as high-resolution interactive Vega-Lite visualizations instead of ASCII art.
15751
+ `;
15752
+ const GGTERM_MARKER = "# ggterm Data Analysis Project";
15753
+ let shouldWriteClaudeMd = !existsSync2(claudeMdPath);
15754
+ if (!shouldWriteClaudeMd) {
15755
+ try {
15756
+ const existing = readFileSync2(claudeMdPath, "utf-8");
15757
+ shouldWriteClaudeMd = existing.startsWith(GGTERM_MARKER);
15758
+ } catch {}
15759
+ }
15760
+ if (shouldWriteClaudeMd) {
15761
+ writeFileSync2(claudeMdPath, claudeMdContent);
15762
+ console.log(" ✓ CLAUDE.md (project instructions for Claude Code)");
15763
+ console.log("");
15764
+ }
15765
+ console.log("Built-in datasets:");
15766
+ console.log(" • iris (150 rows: sepal_length, sepal_width, petal_length, petal_width, species)");
15767
+ console.log(" • mtcars (16 rows: mpg, cyl, hp, wt, name)");
15768
+ console.log("");
15768
15769
  const dataFiles = findDataFiles(cwd);
15769
15770
  if (dataFiles.length > 0) {
15770
15771
  console.log("Data files:");
@@ -15792,9 +15793,9 @@ function handleInit() {
15792
15793
  }
15793
15794
  if (needsInstall) {
15794
15795
  console.log("Try:");
15795
- console.log(' "Show me a scatter plot of x vs y from data.csv"');
15796
- console.log(' "Create a histogram of the age column"');
15797
- console.log(' "Style this like Tufte and export as PNG"');
15796
+ console.log(' npx ggterm-plot iris sepal_length sepal_width species "Iris" point');
15797
+ console.log(" npx ggterm-plot serve # Start live viewer");
15798
+ console.log(' "Plot the iris dataset" # Ask Claude Code');
15798
15799
  console.log("");
15799
15800
  }
15800
15801
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmkBH,wBAAgB,UAAU,IAAI,IAAI,CAyFjC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkgBH,wBAAgB,UAAU,IAAI,IAAI,CAyJjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0eH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAmG/C"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0eH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CA6G/C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggterm/core",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Grammar of Graphics engine for terminals",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",