claude-relay 2.2.0 → 2.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 CHANGED
@@ -185,6 +185,10 @@ npx claude-relay -p 8080 # Specify port
185
185
  npx claude-relay --no-https # Disable HTTPS
186
186
  npx claude-relay --no-update # Skip update check
187
187
  npx claude-relay --debug # Enable debug panel
188
+ npx claude-relay --add . # Add current directory to running daemon
189
+ npx claude-relay --add /path # Add a project by path
190
+ npx claude-relay --remove . # Remove a project
191
+ npx claude-relay --list # List registered projects
188
192
  ```
189
193
 
190
194
  ## Requirements
package/bin/cli.js CHANGED
@@ -18,6 +18,9 @@ var debugMode = false;
18
18
  var autoYes = false;
19
19
  var cliPin = null;
20
20
  var shutdownMode = false;
21
+ var addPath = null;
22
+ var removePath = null;
23
+ var listMode = false;
21
24
 
22
25
  for (var i = 0; i < args.length; i++) {
23
26
  if (args[i] === "-p" || args[i] === "--port") {
@@ -40,8 +43,19 @@ for (var i = 0; i < args.length; i++) {
40
43
  i++;
41
44
  } else if (args[i] === "--shutdown") {
42
45
  shutdownMode = true;
46
+ } else if (args[i] === "--add") {
47
+ addPath = args[i + 1] || ".";
48
+ i++;
49
+ } else if (args[i] === "--remove") {
50
+ removePath = args[i + 1] || null;
51
+ i++;
52
+ } else if (args[i] === "--list") {
53
+ listMode = true;
43
54
  } else if (args[i] === "-h" || args[i] === "--help") {
44
55
  console.log("Usage: claude-relay [-p|--port <port>] [--no-https] [--no-update] [--debug] [-y|--yes] [--pin <pin>] [--shutdown]");
56
+ console.log(" claude-relay --add <path> Add a project to the running daemon");
57
+ console.log(" claude-relay --remove <path> Remove a project from the running daemon");
58
+ console.log(" claude-relay --list List registered projects");
45
59
  console.log("");
46
60
  console.log("Options:");
47
61
  console.log(" -p, --port <port> Port to listen on (default: 2633)");
@@ -51,6 +65,9 @@ for (var i = 0; i < args.length; i++) {
51
65
  console.log(" -y, --yes Skip interactive prompts (accept defaults)");
52
66
  console.log(" --pin <pin> Set 6-digit PIN (use with --yes)");
53
67
  console.log(" --shutdown Shut down the running relay daemon");
68
+ console.log(" --add <path> Add a project directory (use '.' for current)");
69
+ console.log(" --remove <path> Remove a project directory");
70
+ console.log(" --list List all registered projects");
54
71
  process.exit(0);
55
72
  }
56
73
  }
@@ -75,6 +92,93 @@ if (shutdownMode) {
75
92
  return;
76
93
  }
77
94
 
95
+ // --- Handle --add before anything else ---
96
+ if (addPath !== null) {
97
+ var absAdd = path.resolve(addPath);
98
+ try {
99
+ var stat = fs.statSync(absAdd);
100
+ if (!stat.isDirectory()) {
101
+ console.error("Not a directory: " + absAdd);
102
+ process.exit(1);
103
+ }
104
+ } catch (e) {
105
+ console.error("Directory not found: " + absAdd);
106
+ process.exit(1);
107
+ }
108
+ var addConfig = loadConfig();
109
+ isDaemonAliveAsync(addConfig).then(function (alive) {
110
+ if (!alive) {
111
+ console.error("No running daemon. Start with: npx claude-relay");
112
+ process.exit(1);
113
+ }
114
+ sendIPCCommand(socketPath(), { cmd: "add_project", path: absAdd }).then(function (res) {
115
+ if (res.ok) {
116
+ if (res.existing) {
117
+ console.log("Already registered: " + res.slug);
118
+ } else {
119
+ console.log("Added: " + res.slug + " \u2192 " + absAdd);
120
+ }
121
+ process.exit(0);
122
+ } else {
123
+ console.error("Failed: " + (res.error || "unknown error"));
124
+ process.exit(1);
125
+ }
126
+ });
127
+ });
128
+ return;
129
+ }
130
+
131
+ // --- Handle --remove before anything else ---
132
+ if (removePath !== null) {
133
+ var absRemove = path.resolve(removePath);
134
+ var removeConfig = loadConfig();
135
+ isDaemonAliveAsync(removeConfig).then(function (alive) {
136
+ if (!alive) {
137
+ console.error("No running daemon. Start with: npx claude-relay");
138
+ process.exit(1);
139
+ }
140
+ sendIPCCommand(socketPath(), { cmd: "remove_project", path: absRemove }).then(function (res) {
141
+ if (res.ok) {
142
+ console.log("Removed: " + path.basename(absRemove));
143
+ process.exit(0);
144
+ } else {
145
+ console.error("Failed: " + (res.error || "project not found"));
146
+ process.exit(1);
147
+ }
148
+ });
149
+ });
150
+ return;
151
+ }
152
+
153
+ // --- Handle --list before anything else ---
154
+ if (listMode) {
155
+ var listConfig = loadConfig();
156
+ isDaemonAliveAsync(listConfig).then(function (alive) {
157
+ if (!alive) {
158
+ console.error("No running daemon. Start with: npx claude-relay");
159
+ process.exit(1);
160
+ }
161
+ sendIPCCommand(socketPath(), { cmd: "get_status" }).then(function (res) {
162
+ if (!res.ok || !res.projects || res.projects.length === 0) {
163
+ console.log("No projects registered.");
164
+ process.exit(0);
165
+ return;
166
+ }
167
+ console.log("Projects (" + res.projects.length + "):\n");
168
+ for (var p = 0; p < res.projects.length; p++) {
169
+ var proj = res.projects[p];
170
+ var label = " " + proj.slug;
171
+ if (proj.title) label += " (" + proj.title + ")";
172
+ label += "\n " + proj.path;
173
+ console.log(label);
174
+ }
175
+ console.log("");
176
+ process.exit(0);
177
+ });
178
+ });
179
+ return;
180
+ }
181
+
78
182
  var cwd = process.cwd();
79
183
 
80
184
  // --- ANSI helpers ---
package/lib/public/app.js CHANGED
@@ -1623,6 +1623,7 @@ import { initTools, resetToolState, saveToolState, restoreToolState, renderAskUs
1623
1623
  sessionListEl: sessionListEl,
1624
1624
  scrollToBottom: scrollToBottom,
1625
1625
  basePath: basePath,
1626
+ toggleUsagePanel: toggleUsagePanel,
1626
1627
  });
1627
1628
 
1628
1629
  // --- QR code ---
@@ -46,6 +46,21 @@
46
46
  #todo-sticky .todo-sticky-chevron { display: inline-flex; color: var(--text-muted); transition: transform 0.2s; }
47
47
  #todo-sticky .todo-sticky-chevron .lucide { width: 12px; height: 12px; }
48
48
  #todo-sticky.collapsed .todo-sticky-chevron { transform: rotate(-90deg); }
49
+ #todo-sticky .todo-sticky-active { display: none; }
50
+ #todo-sticky.collapsed .todo-sticky-active {
51
+ display: inline-flex;
52
+ align-items: center;
53
+ gap: 4px;
54
+ flex: 1;
55
+ min-width: 0;
56
+ font-size: 11px;
57
+ color: var(--text-secondary);
58
+ overflow: hidden;
59
+ text-overflow: ellipsis;
60
+ white-space: nowrap;
61
+ }
62
+ #todo-sticky.collapsed .todo-sticky-active .lucide { width: 12px; height: 12px; color: var(--accent); flex-shrink: 0; }
63
+ #todo-sticky.collapsed .todo-sticky-title { flex: none; }
49
64
 
50
65
  #todo-sticky .todo-sticky-progress { height: 2px; background: var(--border); }
51
66
  #todo-sticky .todo-sticky-progress-bar { height: 100%; background: var(--success); transition: width 0.3s ease; }
@@ -693,10 +693,16 @@ function updateTodoSticky() {
693
693
  var pct = Math.round(completed / todoItems.length * 100);
694
694
  var wasCollapsed = stickyEl.classList.contains("collapsed");
695
695
 
696
+ var inProgressItem = null;
697
+ for (var j = 0; j < todoItems.length; j++) {
698
+ if (todoItems[j].status === "in_progress") { inProgressItem = todoItems[j]; break; }
699
+ }
700
+
696
701
  var html = '<div class="todo-sticky-inner">' +
697
702
  '<div class="todo-sticky-header">' +
698
703
  '<span class="todo-sticky-icon">' + iconHtml("list-checks") + '</span>' +
699
704
  '<span class="todo-sticky-title">Tasks</span>' +
705
+ (inProgressItem ? '<span class="todo-sticky-active">' + iconHtml("loader", "icon-spin") + ' ' + escapeHtml(inProgressItem.activeForm || inProgressItem.content) + '</span>' : '') +
700
706
  '<span class="todo-sticky-count">' + completed + '/' + todoItems.length + '</span>' +
701
707
  '<span class="todo-sticky-chevron">' + iconHtml("chevron-down") + '</span>' +
702
708
  '</div>' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-relay",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "claude-relay": "./bin/cli.js"