[project] # `clique` on PyPI is taken by an unrelated library (a numerical-collection # manager, still published). The *command* is still `clique`; only the name you # install by differs, which is ordinary — plenty of tools work that way. name = "clique-panel" # Read from clique/__init__.py, so the release process has one number to bump # and the wheel can never disagree with what the panel reports about itself. dynamic = ["version"] description = "Your private clique of CLIs. Folder-organised, CLI-agnostic coding sessions in a browser, persisted in tmux" readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.11" dependencies = [] # deliberate: stdlib only, so it still starts in two years authors = [{ name = "Justin Willhite" }] keywords = ["tmux", "terminal", "session-manager", "web-terminal", "coding-agents", "claude-code", "self-hosted", "multi-agent"] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX :: Linux", "Operating System :: MacOS", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Topic :: Software Development", "Topic :: Terminals :: Terminal Emulators/X Terminals", "Topic :: Utilities", ] # The one opt-in extra. Base CLIque stays dependency-free; storing a # bring-your-own-key provider secret needs real authenticated encryption, and # the stdlib has no cipher — so `pip install 'clique-panel[llm]'` pulls in one # vetted crypto library, and only for operators who actually use that feature. [project.optional-dependencies] llm = ["cryptography>=41"] [project.urls] Homepage = "https://github.com/thejdubb02/clique" Changelog = "https://github.com/thejdubb02/clique/blob/main/CHANGELOG.md" Issues = "https://github.com/thejdubb02/clique/issues" API = "https://github.com/thejdubb02/clique/blob/main/API.md" [project.scripts] clique = "clique.__main__:main" [build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] version = { attr = "clique.__version__" } [tool.setuptools.packages.find] include = ["clique*"] # The panel is the product, and it is all static files. Without this the wheel # ships the server and none of the interface, which starts and serves 404s. [tool.setuptools.package-data] clique = [ "web/*.html", "web/*.css", "web/*.js", "web/*.webmanifest", "web/vendor/*", "web/icons/*", "web/brand/*", "web/art/*", "config/*.toml", ] [tool.ruff] line-length = 100 target-version = "py311" [tool.ruff.lint] # "S" is flake8-bandit. On permanently: this thing hands out a terminal, so a # security regression should fail the build rather than wait to be noticed. # Everything it flags is either fixed or annotated at the line with the reason. select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF", "BLE", "S"] ignore = ["E501"] # long lines are almost always a comment explaining why [tool.ruff.lint.per-file-ignores] "tools/*" = [ "E402", # sys.path insert before imports, on purpose "S101", # asserts are how a test suite states a fact "S108", # /tmp is where a smoke test belongs "S310", "S603", "S607", # the suite drives its own server and its own tmux ] # Running `tmux` and `git` from PATH is not a finding, it is the product: this # is a tmux front end, and pinning an absolute path would break every machine # that installs it somewhere else. Every call passes argv as a list, so no # shell ever sees any of it — which is the actual protection S603 is proxying # for. Annotating fourteen call sites individually would say the same thing # fourteen times and train the reader to skim noqa comments. "clique/tmux.py" = ["S603", "S607"] "clique/__init__.py" = ["S603", "S607"] # Fullwidth punctuation is not a typo in Japanese or Chinese, it is the correct # character. RUF001 cannot know that and flags every one of them. "tools/site_i18n.py" = ["RUF001", "RUF002", "RUF003"]