@flowdot.ai/cli 1.0.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/dist/ui/run.js ADDED
@@ -0,0 +1,132 @@
1
+ // packages/ui/src/run.tsx
2
+ import { useState, useEffect, useRef, useCallback } from "react";
3
+ import { render, Box, Text, useApp, useStdout } from "ink";
4
+ import TextInput from "ink-text-input";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
7
+ var SPINNER_INTERVAL = 300;
8
+ var SlowSpinner = () => {
9
+ const [frame, setFrame] = useState(0);
10
+ useEffect(() => {
11
+ const timer = setInterval(() => {
12
+ setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);
13
+ }, SPINNER_INTERVAL);
14
+ return () => clearInterval(timer);
15
+ }, []);
16
+ return /* @__PURE__ */ jsx(Text, { children: SPINNER_FRAMES[frame] });
17
+ };
18
+ function sendToParent(message) {
19
+ if (process.send) {
20
+ process.send(message);
21
+ }
22
+ }
23
+ function App() {
24
+ const [messages, setMessages] = useState([]);
25
+ const [input, setInput] = useState("");
26
+ const [spinnerState, setSpinnerState] = useState({
27
+ active: false,
28
+ text: ""
29
+ });
30
+ const [isReady, setIsReady] = useState(false);
31
+ const messageIdRef = useRef(0);
32
+ const { exit } = useApp();
33
+ const { stdout } = useStdout();
34
+ const width = stdout?.columns || 80;
35
+ useEffect(() => {
36
+ const handleMessage = (message) => {
37
+ switch (message.type) {
38
+ case "display":
39
+ setSpinnerState({ active: false, text: "" });
40
+ setMessages((prev) => [
41
+ ...prev,
42
+ {
43
+ id: messageIdRef.current++,
44
+ content: message.content,
45
+ color: message.color,
46
+ bold: message.bold
47
+ }
48
+ ]);
49
+ break;
50
+ case "spinner:start":
51
+ setSpinnerState({ active: true, text: message.text });
52
+ break;
53
+ case "spinner:succeed":
54
+ case "spinner:fail":
55
+ case "spinner:warn":
56
+ setSpinnerState({ active: false, text: "" });
57
+ if (message.text) {
58
+ setMessages((prev) => [
59
+ ...prev,
60
+ {
61
+ id: messageIdRef.current++,
62
+ content: message.text,
63
+ color: message.type === "spinner:succeed" ? "green" : message.type === "spinner:fail" ? "red" : "yellow"
64
+ }
65
+ ]);
66
+ }
67
+ break;
68
+ case "clear":
69
+ setMessages([]);
70
+ break;
71
+ case "prompt":
72
+ break;
73
+ case "exit":
74
+ exit();
75
+ process.exit(0);
76
+ break;
77
+ default:
78
+ break;
79
+ }
80
+ };
81
+ process.on("message", handleMessage);
82
+ sendToParent({ type: "ready" });
83
+ setIsReady(true);
84
+ return () => {
85
+ process.removeListener("message", handleMessage);
86
+ };
87
+ }, [exit]);
88
+ const handleSubmit = useCallback((value) => {
89
+ if (!value.trim()) {
90
+ return;
91
+ }
92
+ sendToParent({ type: "input", value });
93
+ setInput("");
94
+ }, []);
95
+ const handleExit = useCallback(() => {
96
+ sendToParent({ type: "exit" });
97
+ exit();
98
+ }, [exit]);
99
+ if (!isReady) {
100
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { color: "cyan", children: "Initializing..." }) });
101
+ }
102
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width, children: [
103
+ /* @__PURE__ */ jsx(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "FlowDot CLI" }) }),
104
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: messages.map((msg) => /* @__PURE__ */ jsx(Text, { color: msg.color || "white", bold: msg.bold, children: msg.content }, msg.id)) }),
105
+ spinnerState.active && /* @__PURE__ */ jsxs(Box, { children: [
106
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(SlowSpinner, {}) }),
107
+ /* @__PURE__ */ jsxs(Text, { children: [
108
+ " ",
109
+ spinnerState.text
110
+ ] })
111
+ ] }),
112
+ /* @__PURE__ */ jsxs(Box, { children: [
113
+ /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "> " }),
114
+ /* @__PURE__ */ jsx(
115
+ TextInput,
116
+ {
117
+ value: input,
118
+ onChange: setInput,
119
+ onSubmit: handleSubmit
120
+ }
121
+ )
122
+ ] }),
123
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Press Ctrl+C to exit" }) })
124
+ ] });
125
+ }
126
+ process.stdin.resume();
127
+ render(/* @__PURE__ */ jsx(App, {}));
128
+ /**
129
+ * @license
130
+ * Copyright 2026 FlowDot
131
+ * SPDX-License-Identifier: Apache-2.0
132
+ */
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@flowdot.ai/cli",
3
+ "version": "1.0.0",
4
+ "description": "Official CLI for FlowDot - Execute workflows, send messages to the agent, and manage your account from the command line",
5
+ "type": "module",
6
+ "bin": {
7
+ "flowdot": "./dist/cli/index.js"
8
+ },
9
+ "workspaces": [
10
+ "packages/*"
11
+ ],
12
+ "scripts": {
13
+ "build": "node esbuild.config.js",
14
+ "build:extension": "npm run build --workspace=flowdot-vscode && npm run package:all --workspace=flowdot-vscode",
15
+ "build:all": "npm run build && npm run build:extension",
16
+ "dev": "node esbuild.config.js --watch",
17
+ "test": "vitest",
18
+ "lint": "eslint .",
19
+ "prepublishOnly": "npm run build:all"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "packages/core/assets",
24
+ "README.md"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/flowdot-llc/flowdot-cli"
32
+ },
33
+ "homepage": "https://flowdot.ai/docs/cli",
34
+ "author": "FlowDot",
35
+ "license": "MIT",
36
+ "engines": {
37
+ "node": ">=20.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/js-yaml": "^4.0.9",
41
+ "@types/node": "^20.11.20",
42
+ "@types/react": "^19.2.0",
43
+ "@types/react-dom": "^19.2.0",
44
+ "@types/uuid": "^10.0.0",
45
+ "@vitest/eslint-plugin": "^1.3.4",
46
+ "cross-env": "^7.0.3",
47
+ "esbuild": "^0.25.0",
48
+ "esbuild-node-externals": "^1.20.1",
49
+ "eslint": "^9.24.0",
50
+ "eslint-config-prettier": "^10.1.2",
51
+ "eslint-plugin-import": "^2.31.0",
52
+ "eslint-plugin-license-header": "^0.8.0",
53
+ "eslint-plugin-react": "^7.37.5",
54
+ "eslint-plugin-react-hooks": "^5.2.0",
55
+ "globals": "^16.0.0",
56
+ "ink-spinner": "^5.0.0",
57
+ "ink-testing-library": "^4.0.0",
58
+ "ink-text-input": "^6.0.0",
59
+ "jest-environment-jsdom": "^30.2.0",
60
+ "prettier": "^3.2.5",
61
+ "typescript": "^5.3.3",
62
+ "typescript-eslint": "^8.30.1",
63
+ "uuid": "^10.0.0",
64
+ "vite-tsconfig-paths": "^5.1.4",
65
+ "vitest": "^3.2.4"
66
+ },
67
+ "dependencies": {
68
+ "@flowdot.ai/api": "^1.0.2",
69
+ "ink": "npm:@jrichman/ink@6.4.6",
70
+ "react": "^19.2.0"
71
+ }
72
+ }