@fui-org/fui-cli 2.0.0 → 2.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/dist/fui.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{enableCompileCache as a}from"node:module";a?.();var{run:e}=await import("./fui-bmg5pnmq.js");await e();
2
+ import{enableCompileCache as a}from"node:module";a?.();var{run:e}=await import("./fui-cx180e19.js");await e();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fui-org/fui-cli",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Token-lean CLI for the FUI low-code platform (Node.js)",
5
5
  "keywords": [
6
6
  "ai",
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "fui-target",
3
+ "version": "1.0.0",
4
+ "description": "Shows the FUI project and module the fui CLI targets, once a Claude Code session runs fui",
5
+ "types": "./types/index.d.ts"
6
+ }
@@ -0,0 +1 @@
1
+ { "modules": ["./register.tsx"] }
@@ -0,0 +1,71 @@
1
+ import { atom, read, update } from "claude-code";
2
+ import type { Engine, Register } from "claude-code";
3
+
4
+ import type { FuiTarget } from "../types";
5
+
6
+ const target = atom({ plugin: "fui-target", key: "target" } as const, null);
7
+
8
+ const FUI_CALL = /(?:^|[\s;&|(])fui\s+([a-z-]+)(?:\s+([a-z-]+))?/;
9
+
10
+ // Mirrors sessionFile() in src/core/session/state.ts.
11
+ async function sessionFile($: Engine, command: string) {
12
+ const key = command.match(/FUI_SESSION=([A-Za-z0-9_-]+)/)?.[1] ?? (await $.env.get("FUI_SESSION")) ?? "default";
13
+ const dir =
14
+ (await $.env.get("FUI_SESSION_DIR")) ??
15
+ (await $.env.get("FUI_MCP_SESSION_DIR")) ??
16
+ `${await $.env.get("HOME")}/.fui-mcp/session`;
17
+ return `${dir}/cli-${key}.json`;
18
+ }
19
+
20
+ async function sync($: Engine, command: string, lastCommand: string) {
21
+ const text = await $.fs.read(await sessionFile($, command)).catch(() => "");
22
+ let state: { target?: { projectId?: string; moduleId?: string } } = {};
23
+ try {
24
+ state = JSON.parse(text || "{}");
25
+ } catch {}
26
+
27
+ await update($, target, () => ({
28
+ project: state.target?.projectId,
29
+ module: state.target?.moduleId,
30
+ lastCommand,
31
+ }));
32
+ }
33
+
34
+ export const register: Register = (on) => {
35
+ on("tool.call", { tool: "Bash" }, async ($, e, next) => {
36
+ const result = await next(e);
37
+ const call = e.command.match(FUI_CALL);
38
+ if (!call) return result;
39
+
40
+ await sync($, e.command, [call[1], call[2]].filter(Boolean).join(" "));
41
+ return result;
42
+ });
43
+
44
+ on("ui.render", { component: "AbovePrompt" }, async ($, e, next) => {
45
+ const current: FuiTarget | null = await read($, target);
46
+ if (e.props.hasSurvey || current === null) return next(e);
47
+
48
+ const { Box, Text } = $.ui.resolve(e);
49
+ return (
50
+ <Box flexDirection="row" columnGap={1}>
51
+ <Text>🧩</Text>
52
+ {current.project ? (
53
+ <Text>
54
+ <Text bold color="cyan">
55
+ {current.project}
56
+ </Text>
57
+ {current.module && (
58
+ <Text>
59
+ <Text dimColor> › </Text>
60
+ <Text bold>{current.module}</Text>
61
+ </Text>
62
+ )}
63
+ </Text>
64
+ ) : (
65
+ <Text dimColor>no active module</Text>
66
+ )}
67
+ {current.lastCommand && <Text dimColor> · fui {current.lastCommand}</Text>}
68
+ </Box>
69
+ );
70
+ });
71
+ };
@@ -0,0 +1,7 @@
1
+ export type FuiTarget = { project?: string; module?: string; lastCommand?: string };
2
+
3
+ declare module "claude-code" {
4
+ interface PluginState {
5
+ "fui-target": { target: FuiTarget | null };
6
+ }
7
+ }