somratpro Claude Sonnet 4.6 commited on
Commit
44ce938
·
1 Parent(s): eb3a3f8

Restore dashboard at / with Paperclip at /app/ (proper fix)

Browse files

Patch ui/src/main.tsx in the Dockerfile build to add basename="/app"
to BrowserRouter. With this, React Router strips the /app prefix
client-side before matching routes — /app/ becomes /, /app/ABC/issues
becomes /ABC/issues — so the company-prefix extractor never sees "app".

Health server:
- / → HuggingClip dashboard (restored)
- /app/* → proxy to Paperclip with /app prefix stripped
- /api/* → proxy pass-through
- /* catch-all → proxy pass-through (assets, sw.js, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (3) hide show
  1. Dockerfile +6 -0
  2. health-server.js +26 -4
  3. start.sh +2 -2
Dockerfile CHANGED
@@ -11,6 +11,12 @@ RUN apt-get update && apt-get install -y \
11
  # Clone Paperclip (depth=1 for speed, uses repo's default branch)
12
  RUN git clone --depth=1 https://github.com/paperclipai/paperclip.git .
13
 
 
 
 
 
 
 
14
  # Patch firstBlockedChainFinding to cap chain depth at 500.
15
  # Default 1MB stack overflows on deep recovery-issue chains created by
16
  # runaway agents. Cycle detection is already in place via the Set; we
 
11
  # Clone Paperclip (depth=1 for speed, uses repo's default branch)
12
  RUN git clone --depth=1 https://github.com/paperclipai/paperclip.git .
13
 
14
+ # Patch React Router to use /app as basename so the health dashboard owns /
15
+ # Without this, <BrowserRouter> sees the full path "/app/" and treats "app"
16
+ # as a company prefix, showing "Company not found".
17
+ RUN sed -i 's|<BrowserRouter>|<BrowserRouter basename="/app">|' ui/src/main.tsx && \
18
+ grep -q 'basename="/app"' ui/src/main.tsx || (echo "PATCH NOT APPLIED to main.tsx" && exit 1)
19
+
20
  # Patch firstBlockedChainFinding to cap chain depth at 500.
21
  # Default 1MB stack overflows on deep recovery-issue chains created by
22
  # runaway agents. Cycle detection is already in place via the Set; we
health-server.js CHANGED
@@ -84,6 +84,10 @@ app.get("/health", async (req, res) => {
84
  // ============================================================================
85
  // Dashboard Route
86
  // ============================================================================
 
 
 
 
87
  app.get("/_status", (req, res) => {
88
  res.send(getDashboardHTML());
89
  });
@@ -93,7 +97,7 @@ app.get("/_status/", (req, res) => {
93
  });
94
 
95
  app.get("/dashboard/", (req, res) => {
96
- res.redirect("/_status");
97
  });
98
 
99
  app.get("/dashboard/status", (req, res) => {
@@ -136,6 +140,24 @@ app.post("/dashboard/uptimerobot/setup", (req, res) => {
136
  // Reverse Proxy Routes
137
  // ============================================================================
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  // Proxy all /api/* requests to Paperclip
140
  app.all("/api/*", async (req, res) => {
141
  const targetPath = req.path;
@@ -599,10 +621,10 @@ function getDashboardHTML() {
599
  </div>
600
  <div class="stat">
601
  <span class="stat-label">UI URL</span>
602
- <span class="stat-value"><span class="code">/</span></span>
603
  </div>
604
  <div class="button-group">
605
- <a href="/" class="button button-primary" target="_blank">Open Paperclip UI</a>
606
  </div>
607
  </div>
608
 
@@ -660,7 +682,7 @@ function getDashboardHTML() {
660
  <div class="card">
661
  <h2>📚 Resources</h2>
662
  <div class="button-group" style="flex-direction: column;">
663
- <a href="/" class="button button-primary" target="_blank">Paperclip Dashboard</a>
664
  <a href="/api/" class="button button-secondary" target="_blank">API Reference</a>
665
  </div>
666
  <div class="stat" style="margin-top: 16px;">
 
84
  // ============================================================================
85
  // Dashboard Route
86
  // ============================================================================
87
+ app.get("/", (req, res) => {
88
+ res.send(getDashboardHTML());
89
+ });
90
+
91
  app.get("/_status", (req, res) => {
92
  res.send(getDashboardHTML());
93
  });
 
97
  });
98
 
99
  app.get("/dashboard/", (req, res) => {
100
+ res.redirect("/");
101
  });
102
 
103
  app.get("/dashboard/status", (req, res) => {
 
140
  // Reverse Proxy Routes
141
  // ============================================================================
142
 
143
+ // Proxy /app/* to Paperclip, stripping the /app prefix.
144
+ // The SPA is built with BrowserRouter basename="/app" so React Router
145
+ // strips the prefix on the client — Paperclip receives clean paths.
146
+ app.all("/app/*", async (req, res) => {
147
+ const targetPath = req.path.replace("/app", "") || "/";
148
+ const query = req.url.includes("?") ? req.url.slice(req.url.indexOf("?")) : "";
149
+ const targetUrl = `http://${PAPERCLIP_HOST}:${PAPERCLIP_PORT}${targetPath}${query}`;
150
+
151
+ try {
152
+ const response = await proxyRequest(req.method, targetUrl, req.headers, req.body);
153
+ Object.keys(response.headers).forEach((key) => res.setHeader(key, response.headers[key]));
154
+ res.status(response.statusCode).send(response.body);
155
+ } catch (error) {
156
+ console.error(`Proxy error: ${error.message}`);
157
+ res.status(503).json({ error: "Paperclip service unavailable", details: error.message });
158
+ }
159
+ });
160
+
161
  // Proxy all /api/* requests to Paperclip
162
  app.all("/api/*", async (req, res) => {
163
  const targetPath = req.path;
 
621
  </div>
622
  <div class="stat">
623
  <span class="stat-label">UI URL</span>
624
+ <span class="stat-value"><span class="code">/app/</span></span>
625
  </div>
626
  <div class="button-group">
627
+ <a href="/app/" class="button button-primary" target="_blank">Open Paperclip UI</a>
628
  </div>
629
  </div>
630
 
 
682
  <div class="card">
683
  <h2>📚 Resources</h2>
684
  <div class="button-group" style="flex-direction: column;">
685
+ <a href="/app/" class="button button-primary" target="_blank">Paperclip Dashboard</a>
686
  <a href="/api/" class="button button-secondary" target="_blank">API Reference</a>
687
  </div>
688
  <div class="stat" style="margin-top: 16px;">
start.sh CHANGED
@@ -258,8 +258,8 @@ fi
258
 
259
  echo "HuggingClip is ready!"
260
  echo ""
261
- echo " Health dashboard : http://localhost:7861/_status"
262
- echo " Paperclip UI : http://localhost:7861/"
263
  echo " API : http://localhost:7861/api/"
264
  echo ""
265
 
 
258
 
259
  echo "HuggingClip is ready!"
260
  echo ""
261
+ echo " Health dashboard : http://localhost:7861/"
262
+ echo " Paperclip UI : http://localhost:7861/app/"
263
  echo " API : http://localhost:7861/api/"
264
  echo ""
265