agentleFS
Sign inSign up

etienne

BulloRosso/etienne/CLAUDE.md

The goal of the the project is to manage isolated projects in a central mounted volume /workspace. All embedding generation MUST go through EmbeddingsService in backend/src/embeddings. Do not import openai, @huggingface/transformers, or any other embedding library directly from feature modules — inject EmbeddingsService and call embed(text) / embedBatch(texts). Default provider is the local self-hosted transformers (Xenova/multilingual-e5-base, ~768-dim, no API key required). OpenAI is opt-in via EMBEDDINGPROVIDER=openai (requires OPENAIAPIKEY). ChromaDB collections are dimension-namespaced (documents${dimension}), so switching providers starts with empty collections…

CLAUDE.md32 starsChanged 17 days ago
  • Reads credentials
  • Deletes or force-pushes
  • Installs packages
# Claude Multi-Tenant

## Components

* /frontend contains the React/Vite/Typescript browser frontend running on :5000
* /backend contains the nest.js/node.js 20 API backend running on :6060
* a docker image name claude-code contains the latest Claude Code developer image

The goal of the the project is to manage isolated projects in a central mounted volume /workspace.

## Embeddings

All embedding generation MUST go through `EmbeddingsService` in [backend/src/embeddings](backend/src/embeddings). Do not import `openai`, `@huggingface/transformers`, or any other embedding library directly from feature modules — inject `EmbeddingsService` and call `embed(text)` / `embedBatch(texts)`.

Default provider is the local self-hosted `transformers` (`Xenova/multilingual-e5-base`, ~768-dim, no API key required). OpenAI is opt-in via `EMBEDDING_PROVIDER=openai` (requires `OPENAI_API_KEY`). ChromaDB collections are dimension-namespaced (`documents_${dimension}`), so switching providers starts with empty collections — documents must be re-ingested.

## Project Structure

Each project in the workspace follows this structure:
```
workspace/<project-name>/
├── .claude/
│   ├── CLAUDE.md          # System prompt/role definition for Claude Code
│   └── settings.json      # Project-specific Claude Code settings
├── data/
│   └── permissions.json   # Tool permissions
└── out/                   # Output files
```

## Working with PDF and Office Format Documents

The standard skill **office-and-pdf-documents** provides document parsing capabilities using the `@llamaindex/liteparse` npm package. It extracts text from documents while preserving spatial layout, and includes built-in OCR for scanned content. LiteParse is the local, open-source version of LlamaIndex's cloud service **LlamaParse**, which could be used for use cases with more complex requirements in regard to parsing quality (e.g. complex tables, multi-column layouts, or heavily formatted documents).

### Supported formats

- **PDF** — native digital PDFs as well as PDFs containing scanned images (processed via built-in OCR)
- **Word** — `.doc`, `.docx`, `.docm`, `.odt`, `.rtf`
- **PowerPoint** — `.ppt`, `.pptx`, `.pptm`, `.odp`
- **Excel / Sheets** — `.xls`, `.xlsx`, `.xlsm`, `.ods`, `.csv`, `.tsv`
- **Images** — `.jpg`, `.jpeg`, `.png`, `.gif`, `.bmp`, `.tiff`, `.webp`, `.svg` (via OCR)

### Binary dependency: LibreOffice

Non-PDF formats (Word, PowerPoint, Excel) are converted to PDF before parsing. This conversion requires **LibreOffice** (`soffice`) to be installed on the system. It is a binary dependency that cannot be installed via npm and must be installed manually.

Before parsing, the skill checks availability by running:

```bash
soffice --version
```

If LibreOffice is missing and the user needs to parse Office documents, the skill will report the issue and provide installation instructions. PDF parsing works without LibreOffice.

### How to start claude code container (obsolete)
```bash
docker run -it \
  --name claude-code \
  -v C:/Data/GitHub/claude-multitenant/workspace:/workspace \
  -e ANTHROPIC_API_KEY=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 \
  claude-code
```

### claude-code docker file (obsolete)
```
FROM node:20

ARG TZ
ENV TZ="$TZ"

ARG CLAUDE_CODE_VERSION=latest

# Install basic development tools and iptables/ipset
RUN apt-get update && apt-get install -y --no-install-recommends \
  less \
  git \
  procps \
  sudo \
  fzf \
  zsh \
  man-db \
  unzip \
  gnupg2 \
  python3 \
  python3-pip \
  gh \
  iptables \
  ipset \
  iproute2 \
  dnsutils \
  aggregate \
  jq \
  nano \
  vim \
  && apt-get clean && rm -rf /var/lib/apt/lists/*

# Ensure default node user has access to /usr/local/share
RUN mkdir -p /usr/local/share/npm-global && \
  chown -R node:node /usr/local/share

ARG USERNAME=node

# Persist bash history.
RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
  && mkdir /commandhistory \
  && touch /commandhistory/.bash_history \
  && chown -R $USERNAME /commandhistory

# Set `DEVCONTAINER` environment variable to help with orientation
ENV DEVCONTAINER=true

# Create workspace and config directories and set permissions
RUN mkdir -p /workspace /home/node/.claude && \
  chown -R node:node /workspace /home/node/.claude

WORKDIR /workspace

ARG GIT_DELTA_VERSION=0.18.2
RUN ARCH=$(dpkg --print-architecture) && \
  wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
  sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
  rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"

# Switch to root to modify sudoers
USER root

# Allow node user to install Python packages
RUN echo 'node ALL=(ALL) NOPASSWD: /usr/bin/pip, /usr/bin/pip3, /usr/local/bin/pip, /usr/local/bin/pip3' >> /etc/sudoers

# Set up non-root user
USER node

# Install global packages
ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
ENV PATH=$PATH:/usr/local/share/npm-global/bin

# Set the default shell to zsh rather than sh
ENV SHELL=/bin/zsh

# Set the default editor and visual
ENV EDITOR=nano
ENV VISUAL=nano

# Default powerline10k theme
ARG ZSH_IN_DOCKER_VERSION=1.2.0
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
  -p git \
  -p fzf \
  -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
  -a "source /usr/share/doc/fzf/examples/completion.zsh" \
  -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
  -x

# Install Claude
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}


# Copy and set up firewall script
COPY init-firewall.sh /usr/local/bin/
USER root
RUN chmod +x /usr/local/bin/init-firewall.sh && \
  echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
  chmod 0440 /etc/sudoers.d/node-firewall
USER node
```

Discussion

Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.

Posts are public.Sign in to post

No one has posted yet. Be the first.