inconvo 1.1.2 → 1.2.1
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/README.md +4 -1
- package/dist/commands/add.js +20 -0
- package/dist/lib/install-dependencies.js +38 -0
- package/dist/templates/packs.js +6 -2
- package/package.json +3 -2
- package/templates/assistant-ui/src/components/assistant-ui/tools/inconvo-chart-colors.ts +15 -0
- package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/inconvo-chart.tsx +5 -8
- package/templates/assistant-ui/src/lib/inconvo/types.ts +118 -0
- package/templates/assistant-ui/tools/inconvo-chart-colors.ts +0 -27
- /package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/inconvo-data-table.tsx +0 -0
- /package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/inconvo-tools.tsx +0 -0
- /package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/message-data-analyst-tool.tsx +0 -0
package/README.md
CHANGED
|
@@ -13,9 +13,12 @@ npx inconvo@latest add assistant-ui-tool-components
|
|
|
13
13
|
Options:
|
|
14
14
|
|
|
15
15
|
- `--cwd <path>` – run the installer against a different project directory
|
|
16
|
-
- `--path <relative>` – override the
|
|
16
|
+
- `--path <relative>` – override the root folder used for file output (defaults to `src`)
|
|
17
17
|
- `--overwrite` – replace any files that already exist without prompting
|
|
18
18
|
- `--yes` – answer "yes" to interactive prompts
|
|
19
|
+
- `--skip-install` – copy files only and skip dependency installation
|
|
20
|
+
|
|
21
|
+
By default the installer writes everything under `src/`, including the tool components and their supporting `src/lib/inconvo/types.ts`. It also installs external dependencies such as `recharts` and `@tanstack/react-table` unless you opt out with `--skip-install`.
|
|
19
22
|
|
|
20
23
|
## Development
|
|
21
24
|
|
package/dist/commands/add.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import { logger } from "../lib/logger.js";
|
|
5
5
|
import { confirmPrompt } from "../lib/prompt.js";
|
|
6
|
+
import { installDependencies } from "../lib/install-dependencies.js";
|
|
6
7
|
import { componentPacks, getPack } from "../templates/packs.js";
|
|
7
8
|
export const addCommand = new Command()
|
|
8
9
|
.name("add")
|
|
@@ -12,6 +13,7 @@ export const addCommand = new Command()
|
|
|
12
13
|
.option("-o, --overwrite", "overwrite existing files without prompting", false)
|
|
13
14
|
.option("-c, --cwd <cwd>", "working directory that will receive the files", process.cwd())
|
|
14
15
|
.option("-p, --path <path>", "relative path where the pack should be written")
|
|
16
|
+
.option("--skip-install", "skip installing npm dependencies", false)
|
|
15
17
|
.action(async (packName, opts) => {
|
|
16
18
|
const pack = getPack(packName);
|
|
17
19
|
if (!pack) {
|
|
@@ -68,6 +70,24 @@ export const addCommand = new Command()
|
|
|
68
70
|
if (replaced.size) {
|
|
69
71
|
logger.info(`Overwrote ${replaced.size} file(s).`);
|
|
70
72
|
}
|
|
73
|
+
if (pack.dependencies) {
|
|
74
|
+
const depList = Object.entries(pack.dependencies).map(([name, version]) => `${name}@${version}`);
|
|
75
|
+
if (!depList.length)
|
|
76
|
+
return;
|
|
77
|
+
if (opts.skipInstall) {
|
|
78
|
+
logger.warn(`Skipping dependency installation (--skip-install). Please install manually:\n ${depList.join(" ")}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
try {
|
|
82
|
+
await installDependencies(pack.dependencies, cwd);
|
|
83
|
+
logger.success("Dependencies installed.");
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger.error(`Failed to install dependencies automatically. Please install manually: ${depList.join(" ")}`);
|
|
87
|
+
logger.error(error?.message ?? String(error));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
71
91
|
logger.success(`Installed ${pack.name}!`);
|
|
72
92
|
});
|
|
73
93
|
async function collectFiles(dir) {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { detect } from "detect-package-manager";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
4
|
+
const installArgsMap = {
|
|
5
|
+
npm: ["install", "--save"],
|
|
6
|
+
pnpm: ["add"],
|
|
7
|
+
yarn: ["add"],
|
|
8
|
+
bun: ["add"],
|
|
9
|
+
};
|
|
10
|
+
export async function installDependencies(dependencies, cwd) {
|
|
11
|
+
const depList = Object.entries(dependencies).map(([name, version]) => version ? `${name}@${version}` : name);
|
|
12
|
+
if (!depList.length)
|
|
13
|
+
return;
|
|
14
|
+
const packageManager = await detect({ cwd });
|
|
15
|
+
const args = installArgsMap[packageManager]
|
|
16
|
+
? [...installArgsMap[packageManager], ...depList]
|
|
17
|
+
: ["install", ...depList];
|
|
18
|
+
logger.step(`Installing dependencies with ${packageManager}: ${depList.join(", ")}`);
|
|
19
|
+
await runCommand(packageManager, args, cwd);
|
|
20
|
+
}
|
|
21
|
+
function runCommand(command, args, cwd) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const child = spawn(command, args, {
|
|
24
|
+
cwd,
|
|
25
|
+
stdio: "inherit",
|
|
26
|
+
shell: process.platform === "win32",
|
|
27
|
+
});
|
|
28
|
+
child.on("close", (code) => {
|
|
29
|
+
if (code === 0) {
|
|
30
|
+
resolve();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
reject(new Error(`${command} exited with code ${code}`));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
child.on("error", (error) => reject(error));
|
|
37
|
+
});
|
|
38
|
+
}
|
package/dist/templates/packs.js
CHANGED
|
@@ -3,8 +3,12 @@ export const componentPacks = {
|
|
|
3
3
|
"assistant-ui-tool-components": {
|
|
4
4
|
name: "assistant-ui-tool-components",
|
|
5
5
|
description: "Inconvo-flavored assistant-ui tools and supporting components.",
|
|
6
|
-
templateDir: resolveFromRoot("templates", "assistant-ui", "
|
|
7
|
-
targetDir: "src
|
|
6
|
+
templateDir: resolveFromRoot("templates", "assistant-ui", "src"),
|
|
7
|
+
targetDir: "src",
|
|
8
|
+
dependencies: {
|
|
9
|
+
recharts: "^3.5.1",
|
|
10
|
+
"@tanstack/react-table": "^8.21.3",
|
|
11
|
+
},
|
|
8
12
|
},
|
|
9
13
|
};
|
|
10
14
|
export function getPack(name) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inconvo",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "CLI for installing Inconvo assistant-ui tool components into any project.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"chalk": "^5.3.0",
|
|
21
|
-
"commander": "^14.0.0"
|
|
21
|
+
"commander": "^14.0.0",
|
|
22
|
+
"detect-package-manager": "^3.0.2"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const chartColorVars = [
|
|
2
|
+
"var(--chart-1)",
|
|
3
|
+
"var(--chart-2)",
|
|
4
|
+
"var(--chart-3)",
|
|
5
|
+
"var(--chart-4)",
|
|
6
|
+
"var(--chart-5)",
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export const buildChartPalette = (seriesCount: number) => {
|
|
10
|
+
if (seriesCount <= 0) return [];
|
|
11
|
+
return Array.from({ length: seriesCount }, (_, index) => {
|
|
12
|
+
const colorIndex = index % chartColorVars.length;
|
|
13
|
+
return chartColorVars[colorIndex] ?? "var(--chart-series-primary)";
|
|
14
|
+
});
|
|
15
|
+
};
|
package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/inconvo-chart.tsx
RENAMED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useMemo, type ReactNode } from "react";
|
|
4
|
-
import { useTheme } from "next-themes";
|
|
5
4
|
import {
|
|
6
5
|
ResponsiveContainer,
|
|
7
6
|
LineChart as RechartsLineChart,
|
|
@@ -17,7 +16,7 @@ import {
|
|
|
17
16
|
} from "recharts";
|
|
18
17
|
|
|
19
18
|
import type { InconvoChartData, InconvoChartType } from "~/lib/inconvo/types";
|
|
20
|
-
import {
|
|
19
|
+
import { buildChartPalette } from "~/components/assistant-ui/tools/inconvo-chart-colors";
|
|
21
20
|
|
|
22
21
|
interface InconvoChartProps {
|
|
23
22
|
data: InconvoChartData;
|
|
@@ -107,8 +106,6 @@ export const InconvoChart = ({
|
|
|
107
106
|
xLabel,
|
|
108
107
|
yLabel,
|
|
109
108
|
}: InconvoChartProps) => {
|
|
110
|
-
const { resolvedTheme } = useTheme();
|
|
111
|
-
|
|
112
109
|
const chartData = useMemo(() => {
|
|
113
110
|
return data.labels.map((label, index) => {
|
|
114
111
|
const row: { name: string; [key: string]: string | number } = {
|
|
@@ -121,10 +118,10 @@ export const InconvoChart = ({
|
|
|
121
118
|
});
|
|
122
119
|
}, [data]);
|
|
123
120
|
|
|
124
|
-
const palette = useMemo(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
const palette = useMemo(
|
|
122
|
+
() => buildChartPalette(data.datasets.length),
|
|
123
|
+
[data.datasets.length],
|
|
124
|
+
);
|
|
128
125
|
|
|
129
126
|
const axisColor = "var(--muted-foreground)";
|
|
130
127
|
const textColor = "var(--foreground)";
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export type InconvoChartType = "bar" | "line";
|
|
2
|
+
|
|
3
|
+
export interface InconvoChartDataset {
|
|
4
|
+
name: string;
|
|
5
|
+
values: number[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface InconvoChartData {
|
|
9
|
+
labels: string[];
|
|
10
|
+
datasets: InconvoChartDataset[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface InconvoChart {
|
|
14
|
+
data: InconvoChartData;
|
|
15
|
+
title?: string;
|
|
16
|
+
xLabel?: string;
|
|
17
|
+
yLabel?: string;
|
|
18
|
+
type: InconvoChartType;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface InconvoTable {
|
|
22
|
+
head: string[];
|
|
23
|
+
body: string[][];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type InconvoResponseType = "text" | "chart" | "table";
|
|
27
|
+
|
|
28
|
+
export interface InconvoResponse {
|
|
29
|
+
id?: string;
|
|
30
|
+
conversationId?: string;
|
|
31
|
+
message: string;
|
|
32
|
+
type: InconvoResponseType;
|
|
33
|
+
chart?: InconvoChart;
|
|
34
|
+
table?: InconvoTable;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const isStringArray = (value: unknown): value is string[] => {
|
|
38
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const isNumberArray = (value: unknown): value is number[] => {
|
|
42
|
+
return Array.isArray(value) && value.every((item) => typeof item === "number");
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const isDataset = (value: unknown): value is InconvoChartDataset => {
|
|
46
|
+
return (
|
|
47
|
+
typeof value === "object" &&
|
|
48
|
+
value !== null &&
|
|
49
|
+
typeof (value as InconvoChartDataset).name === "string" &&
|
|
50
|
+
isNumberArray((value as InconvoChartDataset).values)
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const isChartData = (value: unknown): value is InconvoChartData => {
|
|
55
|
+
return (
|
|
56
|
+
typeof value === "object" &&
|
|
57
|
+
value !== null &&
|
|
58
|
+
isStringArray((value as InconvoChartData).labels) &&
|
|
59
|
+
Array.isArray((value as InconvoChartData).datasets) &&
|
|
60
|
+
(value as InconvoChartData).datasets.every(isDataset)
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const isChart = (value: unknown): value is InconvoChart => {
|
|
65
|
+
return (
|
|
66
|
+
typeof value === "object" &&
|
|
67
|
+
value !== null &&
|
|
68
|
+
((value as InconvoChart).type === "bar" || (value as InconvoChart).type === "line") &&
|
|
69
|
+
isChartData((value as InconvoChart).data)
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const isTable = (value: unknown): value is InconvoTable => {
|
|
74
|
+
return (
|
|
75
|
+
typeof value === "object" &&
|
|
76
|
+
value !== null &&
|
|
77
|
+
isStringArray((value as InconvoTable).head) &&
|
|
78
|
+
Array.isArray((value as InconvoTable).body) &&
|
|
79
|
+
(value as InconvoTable).body.every(isStringArray)
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const isInconvoResponse = (value: unknown): value is InconvoResponse => {
|
|
84
|
+
if (typeof value !== "object" || value === null) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const candidate = value as InconvoResponse;
|
|
89
|
+
if (typeof candidate.message !== "string") {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (candidate.type !== "text" && candidate.type !== "chart" && candidate.type !== "table") {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (candidate.type === "chart" && !isChart(candidate.chart)) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (candidate.type === "table" && !isTable(candidate.table)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return true;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const parseInconvoResponse = (
|
|
109
|
+
value: unknown,
|
|
110
|
+
): InconvoResponse | null => {
|
|
111
|
+
try {
|
|
112
|
+
const parsed: unknown =
|
|
113
|
+
typeof value === "string" ? JSON.parse(value) : value;
|
|
114
|
+
return isInconvoResponse(parsed) ? parsed : null;
|
|
115
|
+
} catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const clamp = (value: number, min = 0, max = 1) =>
|
|
2
|
-
Math.min(Math.max(value, min), max);
|
|
3
|
-
|
|
4
|
-
const lightnessToGrayHex = (lightness: number) => {
|
|
5
|
-
const channel = Math.round(clamp(lightness) * 255)
|
|
6
|
-
.toString(16)
|
|
7
|
-
.padStart(2, "0");
|
|
8
|
-
return `#${channel}${channel}${channel}`;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const buildGreyscalePalette = (
|
|
12
|
-
seriesCount: number,
|
|
13
|
-
isDarkMode: boolean,
|
|
14
|
-
) => {
|
|
15
|
-
if (seriesCount <= 0) return [];
|
|
16
|
-
if (seriesCount === 1) {
|
|
17
|
-
return [lightnessToGrayHex(isDarkMode ? 0.78 : 0.5)];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const start = isDarkMode ? 0.95 : 0.8;
|
|
21
|
-
const end = isDarkMode ? 0.55 : 0.15;
|
|
22
|
-
const step = (end - start) / (seriesCount - 1);
|
|
23
|
-
|
|
24
|
-
return Array.from({ length: seriesCount }, (_, index) =>
|
|
25
|
-
lightnessToGrayHex(start + step * index),
|
|
26
|
-
);
|
|
27
|
-
};
|
/package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/inconvo-data-table.tsx
RENAMED
|
File without changes
|
/package/templates/assistant-ui/{tools → src/components/assistant-ui/tools}/inconvo-tools.tsx
RENAMED
|
File without changes
|
|
File without changes
|