fluxflow-cli 1.10.0 β 1.10.2
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 +12 -1
- package/dist/fluxflow.js +74 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# π Flux Flow (`fluxflow-cli`)
|
|
2
2
|

|
|
3
3
|
|
|
4
|
+
<p align="left">
|
|
5
|
+
<a href="https://github.com/KushalRoyChowdhury/fluxflow-cli"><img src="https://img.shields.io/badge/FluxFlow-v1.10.0-blue?style=plastic" alt="FluxFlow Version"></a>
|
|
6
|
+
<a href="https://deepmind.google"><img src="https://img.shields.io/badge/Engine-Gemma%204-red?style=plastic" alt="Engine Gemma 4"></a>
|
|
7
|
+
<a href="https://pollinations.ai"><img src="https://img.shields.io/badge/Built%20With-pollinations.ai-cyan?style=plastic" alt="Built With pollinations.ai"></a>
|
|
8
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=plastic" alt="License MIT"></a>
|
|
9
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-%3E%3D20-green?style=plastic" alt="Node Compatibility"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
4
12
|
### *The High-Fidelity Agentic Terminal for the Flux Era.*
|
|
5
13
|
|
|
6
14
|
**Flux Flow** is not just another CLIβit's a high-speed, sassy, and goal-oriented CLI AI Agent powered by the latest Gemini/Gemma frontier models. Designed for developers who demand a premium UI/UX while managing complex file-system tasks, web research, and autonomous workflows.
|
|
@@ -30,7 +38,10 @@ Experience a terminal UI that feels alive. Built with **Ink** and **React**, Flu
|
|
|
30
38
|
- **Dynamic Status Bar**: Real-time telemetry showing your "Neural Headroom" (token usage), Thinking Level, and Session ID.
|
|
31
39
|
|
|
32
40
|
### π¨ **Creative & Visual Sovereignty**
|
|
33
|
-
Generate gorgeous, high-fidelity images directly from the command line using Pollinations AI. Use the `/image` command or ask the agent to create visuals. Features
|
|
41
|
+
Generate gorgeous, high-fidelity images directly from the command line using [Pollinations AI](https://pollinations.ai). Use the `/image` command or ask the agent to create visuals. Features:
|
|
42
|
+
- **Customizable Presets**: Supports models like Flux, ZImage, Qwen, and Nanobanana-Pro, custom aspect ratios, and randomized seeds.
|
|
43
|
+
- **Budget Telemetry**: Real-time credits tracker displayed in sleek high-contrast Ink terminal boxes.
|
|
44
|
+
- **PNG Metadata Embedding**: Autonomously injects custom `tEXt` metadata chunks (Title, Software, Author, Seed, Model, and exact Prompt details) straight into the output image headers.
|
|
34
45
|
|
|
35
46
|
### ποΈ **Native Multimodality**
|
|
36
47
|
Flux Flow can now see! Use the `view_file` tool to analyze images (JPG, PNG) or deep-dive into PDF technical papers. The agent extracts high-fidelity visual context natively, making it a true multimodal companion.
|
package/dist/fluxflow.js
CHANGED
|
@@ -808,9 +808,21 @@ var init_paths = __esm({
|
|
|
808
808
|
});
|
|
809
809
|
|
|
810
810
|
// src/utils/secrets.js
|
|
811
|
+
var secrets_exports = {};
|
|
812
|
+
__export(secrets_exports, {
|
|
813
|
+
getAPIKey: () => getAPIKey,
|
|
814
|
+
getSearchSecrets: () => getSearchSecrets,
|
|
815
|
+
getSecret: () => getSecret,
|
|
816
|
+
removeAPIKey: () => removeAPIKey,
|
|
817
|
+
removeSecret: () => removeSecret,
|
|
818
|
+
saveAPIKey: () => saveAPIKey,
|
|
819
|
+
saveSearchId: () => saveSearchId,
|
|
820
|
+
saveSearchKey: () => saveSearchKey,
|
|
821
|
+
saveSecret: () => saveSecret
|
|
822
|
+
});
|
|
811
823
|
import fs3 from "fs-extra";
|
|
812
824
|
import path3 from "path";
|
|
813
|
-
var SECRET_FILE, getAPIKey, saveSecret, saveAPIKey, removeSecret, removeAPIKey;
|
|
825
|
+
var SECRET_FILE, getAPIKey, getSecret, saveSecret, getSearchSecrets, saveAPIKey, saveSearchKey, saveSearchId, removeSecret, removeAPIKey;
|
|
814
826
|
var init_secrets = __esm({
|
|
815
827
|
"src/utils/secrets.js"() {
|
|
816
828
|
init_crypto();
|
|
@@ -824,13 +836,34 @@ var init_secrets = __esm({
|
|
|
824
836
|
}
|
|
825
837
|
return null;
|
|
826
838
|
};
|
|
839
|
+
getSecret = async (key) => {
|
|
840
|
+
try {
|
|
841
|
+
const secrets = readEncryptedJson(SECRET_FILE, {});
|
|
842
|
+
return secrets[key] || null;
|
|
843
|
+
} catch (e) {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
};
|
|
827
847
|
saveSecret = async (key, value) => {
|
|
828
848
|
await fs3.ensureDir(SECRET_DIR);
|
|
829
849
|
let current = readEncryptedJson(SECRET_FILE, {});
|
|
830
850
|
current[key] = value;
|
|
831
851
|
writeEncryptedJson(SECRET_FILE, current);
|
|
832
852
|
};
|
|
853
|
+
getSearchSecrets = async () => {
|
|
854
|
+
try {
|
|
855
|
+
const secrets = readEncryptedJson(SECRET_FILE, {});
|
|
856
|
+
return {
|
|
857
|
+
key: secrets.GOOGLE_API_KEY || secrets.API_KEY,
|
|
858
|
+
cx: secrets.SEARCH_ID
|
|
859
|
+
};
|
|
860
|
+
} catch (e) {
|
|
861
|
+
}
|
|
862
|
+
return { key: null, cx: null };
|
|
863
|
+
};
|
|
833
864
|
saveAPIKey = async (apiKey) => saveSecret("API_KEY", apiKey);
|
|
865
|
+
saveSearchKey = async (key) => saveSecret("GOOGLE_API_KEY", key);
|
|
866
|
+
saveSearchId = async (id) => saveSecret("SEARCH_ID", id);
|
|
834
867
|
removeSecret = async (key) => {
|
|
835
868
|
try {
|
|
836
869
|
const secrets = readEncryptedJson(SECRET_FILE, {});
|
|
@@ -2658,10 +2691,21 @@ var init_settings = __esm({
|
|
|
2658
2691
|
}
|
|
2659
2692
|
};
|
|
2660
2693
|
loadSettings = async () => {
|
|
2694
|
+
let settingsObj = { ...DEFAULT_SETTINGS };
|
|
2661
2695
|
try {
|
|
2662
2696
|
if (await fs14.exists(SETTINGS_FILE)) {
|
|
2663
2697
|
const saved = await fs14.readJson(SETTINGS_FILE);
|
|
2664
|
-
|
|
2698
|
+
if (saved.imageSettings && saved.imageSettings.apiKey) {
|
|
2699
|
+
try {
|
|
2700
|
+
const legacyKey = saved.imageSettings.apiKey;
|
|
2701
|
+
const { saveSecret: saveSecret2 } = await Promise.resolve().then(() => (init_secrets(), secrets_exports));
|
|
2702
|
+
await saveSecret2("POLLINATIONS_API_KEY", legacyKey);
|
|
2703
|
+
saved.imageSettings.apiKey = "";
|
|
2704
|
+
await fs14.writeJson(SETTINGS_FILE, saved, { spaces: 2 });
|
|
2705
|
+
} catch (e) {
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
settingsObj = {
|
|
2665
2709
|
...DEFAULT_SETTINGS,
|
|
2666
2710
|
...saved,
|
|
2667
2711
|
quotas: { ...DEFAULT_SETTINGS.quotas, ...saved.quotas },
|
|
@@ -2669,16 +2713,26 @@ var init_settings = __esm({
|
|
|
2669
2713
|
profileData: { ...DEFAULT_SETTINGS.profileData, ...saved.profileData },
|
|
2670
2714
|
imageSettings: { ...DEFAULT_SETTINGS.imageSettings, ...saved.imageSettings }
|
|
2671
2715
|
};
|
|
2672
|
-
if (merged.showFullThinking === false) {
|
|
2673
|
-
merged.showFullThinking = true;
|
|
2674
|
-
await fs14.writeJson(SETTINGS_FILE, merged, { spaces: 2 });
|
|
2675
|
-
}
|
|
2676
|
-
return merged;
|
|
2677
2716
|
}
|
|
2678
2717
|
} catch (err) {
|
|
2679
2718
|
console.error("Failed to load settings:", err);
|
|
2680
2719
|
}
|
|
2681
|
-
|
|
2720
|
+
try {
|
|
2721
|
+
const { getSecret: getSecret2 } = await Promise.resolve().then(() => (init_secrets(), secrets_exports));
|
|
2722
|
+
const customApiKey = await getSecret2("POLLINATIONS_API_KEY");
|
|
2723
|
+
if (customApiKey) {
|
|
2724
|
+
settingsObj.imageSettings.apiKey = customApiKey;
|
|
2725
|
+
}
|
|
2726
|
+
} catch (e) {
|
|
2727
|
+
}
|
|
2728
|
+
if (settingsObj.showFullThinking === false) {
|
|
2729
|
+
settingsObj.showFullThinking = true;
|
|
2730
|
+
try {
|
|
2731
|
+
await fs14.writeJson(SETTINGS_FILE, settingsObj, { spaces: 2 });
|
|
2732
|
+
} catch (e) {
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
return settingsObj;
|
|
2682
2736
|
};
|
|
2683
2737
|
migrateToExternal = async (newPath) => {
|
|
2684
2738
|
const { FLUXFLOW_DIR: FLUXFLOW_DIR2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
|
|
@@ -2702,7 +2756,19 @@ var init_settings = __esm({
|
|
|
2702
2756
|
if (!current.systemSettings.useExternalData && settings.systemSettings?.useExternalData && settings.systemSettings?.externalDataPath) {
|
|
2703
2757
|
await migrateToExternal(settings.systemSettings.externalDataPath);
|
|
2704
2758
|
}
|
|
2759
|
+
if (settings.imageSettings && settings.imageSettings.apiKey !== void 0) {
|
|
2760
|
+
const { saveSecret: saveSecret2, removeSecret: removeSecret2 } = await Promise.resolve().then(() => (init_secrets(), secrets_exports));
|
|
2761
|
+
const keyToSave = settings.imageSettings.apiKey;
|
|
2762
|
+
if (keyToSave) {
|
|
2763
|
+
await saveSecret2("POLLINATIONS_API_KEY", keyToSave);
|
|
2764
|
+
} else {
|
|
2765
|
+
await removeSecret2("POLLINATIONS_API_KEY");
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2705
2768
|
const updated = { ...current, ...settings };
|
|
2769
|
+
if (updated.imageSettings) {
|
|
2770
|
+
updated.imageSettings = { ...updated.imageSettings, apiKey: "" };
|
|
2771
|
+
}
|
|
2706
2772
|
await fs14.ensureDir(path13.dirname(SETTINGS_FILE));
|
|
2707
2773
|
await fs14.writeJson(SETTINGS_FILE, updated, { spaces: 2 });
|
|
2708
2774
|
return true;
|