flowgraphapp 0.1.1__py3-none-any.whl

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.
@@ -0,0 +1,118 @@
1
+ """Courtesy update check — modelled on pip's self_outdated_check.
2
+
3
+ - Queries https://pypi.org/pypi/flowgraphapp/json (no telemetry, decoupled from any
4
+ analytics) at most once per TTL, caching the result in a per-user statefile.
5
+ - Fully non-blocking (background daemon thread) and crash-proof (all exceptions
6
+ swallowed) — never delays startup, never errors when offline.
7
+ - Opt-out via FLOWGRAPH_NO_UPDATE_CHECK=1, the --no-update-check flag, or config.
8
+ - Never auto-installs. Prints a calm one-line notice with the upgrade command,
9
+ pipx-aware. (Silent auto-update is a supply-chain risk — see docs/18 §updates.)
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import os
16
+ import sys
17
+ import threading
18
+ import time
19
+ from typing import Callable, Optional
20
+
21
+ from . import __version__
22
+ from .config import cache_dir
23
+
24
+ DIST_NAME = "flowgraphapp"
25
+ PYPI_JSON_URL = f"https://pypi.org/pypi/{DIST_NAME}/json"
26
+ TTL_SECONDS = 24 * 3600
27
+
28
+
29
+ def opted_out() -> bool:
30
+ return os.environ.get("FLOWGRAPH_NO_UPDATE_CHECK", "").lower() in ("1", "true", "yes", "on")
31
+
32
+
33
+ def installed_version() -> str:
34
+ try:
35
+ from importlib.metadata import version
36
+ return version(DIST_NAME)
37
+ except Exception:
38
+ return __version__
39
+
40
+
41
+ def _state_file():
42
+ return cache_dir() / "update-check.json"
43
+
44
+
45
+ def _read_cache() -> Optional[dict]:
46
+ try:
47
+ return json.loads(_state_file().read_text(encoding="utf-8"))
48
+ except Exception:
49
+ return None
50
+
51
+
52
+ def _write_cache(latest: str) -> None:
53
+ try:
54
+ _state_file().write_text(
55
+ json.dumps({"last_check": time.time(), "latest": latest}), encoding="utf-8"
56
+ )
57
+ except Exception:
58
+ pass
59
+
60
+
61
+ def _is_newer(latest: str, current: str) -> bool:
62
+ try:
63
+ from packaging.version import Version
64
+ return Version(latest) > Version(current)
65
+ except Exception:
66
+ # Conservative fallback: only flag on a clean numeric-tuple comparison.
67
+ def parts(v):
68
+ return tuple(int(x) for x in v.split(".") if x.isdigit())
69
+ try:
70
+ return parts(latest) > parts(current)
71
+ except Exception:
72
+ return False
73
+
74
+
75
+ def _fetch_latest(timeout: float = 2.5) -> Optional[str]:
76
+ try:
77
+ import httpx
78
+ r = httpx.get(PYPI_JSON_URL, timeout=timeout, headers={"accept": "application/json"})
79
+ if r.status_code == 200:
80
+ return r.json()["info"]["version"]
81
+ except Exception:
82
+ return None
83
+ return None
84
+
85
+
86
+ def _upgrade_command() -> str:
87
+ # pipx installs live in a dedicated venv; plain `pip install` inside it can break it.
88
+ if "PIPX_HOME" in os.environ or os.sep + "pipx" + os.sep in (sys.prefix or ""):
89
+ return f"pipx upgrade {DIST_NAME}"
90
+ return f"pip install -U {DIST_NAME}"
91
+
92
+
93
+ def _run(emit: Callable[[str], None]) -> None:
94
+ try:
95
+ current = installed_version()
96
+ cache = _read_cache()
97
+ latest = None
98
+ if cache and (time.time() - cache.get("last_check", 0)) < TTL_SECONDS:
99
+ latest = cache.get("latest")
100
+ else:
101
+ latest = _fetch_latest()
102
+ if latest:
103
+ _write_cache(latest)
104
+ if latest and _is_newer(latest, current):
105
+ emit(
106
+ f"A new version of FlowGraph is available: {current} -> {latest}. "
107
+ f"Upgrade with: {_upgrade_command()}"
108
+ )
109
+ except Exception:
110
+ pass # never let the courtesy check surface an error
111
+
112
+
113
+ def check_in_background(emit: Optional[Callable[[str], None]] = None) -> None:
114
+ """Spawn a daemon thread to check + emit. No-op if opted out."""
115
+ if opted_out():
116
+ return
117
+ out = emit or (lambda msg: print(f"[flowgraph] {msg}", file=sys.stderr))
118
+ threading.Thread(target=_run, args=(out,), daemon=True).start()
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: flowgraphapp
3
+ Version: 0.1.1
4
+ Summary: FlowGraph — local-first knowledge-graph canvas + AI planner, run securely on your own machine.
5
+ Project-URL: Homepage, https://flow-graph.com
6
+ Author: Naveen
7
+ License: FlowGraph — Proprietary License
8
+ Copyright (c) 2026 Naveen. All rights reserved.
9
+
10
+ This software and its source code (the "Software") are the confidential and
11
+ proprietary property of the copyright holder. No license, right, or permission
12
+ is granted to any person to use, copy, modify, merge, publish, distribute,
13
+ sublicense, sell, or create derivative works of the Software, in whole or in
14
+ part, without the prior written consent of the copyright holder.
15
+
16
+ Unauthorized copying, distribution, or use of the Software, via any medium, is
17
+ strictly prohibited.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21
+ FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
23
+ IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN
24
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ License-File: LICENSE
26
+ Keywords: ai,canvas,graph,knowledge-graph,local-first,planner
27
+ Classifier: Environment :: Web Environment
28
+ Classifier: Framework :: FastAPI
29
+ Classifier: Intended Audience :: End Users/Desktop
30
+ Classifier: License :: Other/Proprietary License
31
+ Classifier: Operating System :: OS Independent
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: Topic :: Office/Business
34
+ Requires-Python: >=3.9
35
+ Requires-Dist: fastapi>=0.115
36
+ Requires-Dist: httpx>=0.27
37
+ Requires-Dist: keyring>=25.0
38
+ Requires-Dist: packaging>=23.0
39
+ Requires-Dist: platformdirs>=4.2
40
+ Requires-Dist: typer>=0.12
41
+ Requires-Dist: uvicorn[standard]>=0.30
42
+ Provides-Extra: dev
43
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
44
+ Requires-Dist: pytest>=8; extra == 'dev'
45
+ Provides-Extra: local-embeddings
46
+ Description-Content-Type: text/markdown
47
+
48
+ # FlowGraph — local server (`flowgraphapp`)
49
+
50
+ Run FlowGraph — the local-first knowledge-graph canvas + AI planner — on your own
51
+ machine. Same app as [flow-graph.com](https://flow-graph.com), served from a hardened
52
+ localhost server; your data stays in your browser, and (optionally) your AI key stays
53
+ in your OS keychain instead of the browser.
54
+
55
+ ## Install
56
+
57
+ **From PyPI** (once published):
58
+
59
+ ```bash
60
+ pip install flowgraphapp # or, isolated: pipx install flowgraphapp
61
+ flowgraph # serves http://127.0.0.1:8765 and opens your browser
62
+ ```
63
+
64
+ **From source** (works today, before the PyPI release):
65
+
66
+ ```bash
67
+ # 1. build the frontend once
68
+ cd app && npm run build && cd ..
69
+ # 2. install the local server (use a venv or pipx to keep it isolated)
70
+ cd server && pip install .
71
+ # 3. run it
72
+ flowgraph
73
+ ```
74
+
75
+ Stop with `Ctrl-C`. Options: `flowgraph --port 0` (auto-pick a free port),
76
+ `--no-open` (don't open the browser), `flowgraph --help`.
77
+
78
+ ## Why local
79
+
80
+ - **Offline / air-gapped** — no Cloudflare, no network required for the app itself.
81
+ - **Privacy / data locality** — your graph lives in the browser's IndexedDB on this machine.
82
+ - **On-device models** — point at Ollama / LM Studio for zero-key, zero-cost AI.
83
+ - **No size ceiling** — not bound by hosting per-file limits as the app grows.
84
+
85
+ ## AI
86
+
87
+ Local-model-first: if a local runtime (Ollama `:11434`, LM Studio `:1234`) is reachable,
88
+ it's used with **no key**. Otherwise bring your own provider key — stored in the OS
89
+ keychain, used server-side, **never sent to the browser**:
90
+
91
+ ```bash
92
+ flowgraph keys set anthropic # or openrouter / openai / google / deepseek
93
+ flowgraph keys list # shows source, never the key
94
+ ```
95
+
96
+ ## Security (safe by default)
97
+
98
+ Binds **loopback only** (`127.0.0.1`); a per-session token is required (delivered via the
99
+ terminal + a `0600` file; the auto-opened URL carries a one-time ticket, never the token).
100
+ Host-header allow-listing blocks DNS-rebinding from websites you visit; Origin checks,
101
+ strict CSP, and security headers apply to every route. Exposing beyond loopback
102
+ (`--allow-lan`) requires TLS. See `docs/18-local-server.md` for the full threat model.
103
+
104
+ ## Updates
105
+
106
+ `pip install -U flowgraphapp` (or `flowgraph upgrade`) updates the app and server together;
107
+ your data is untouched. A calm one-line "update available" notice appears at startup —
108
+ disable with `FLOWGRAPH_NO_UPDATE_CHECK=1`.
@@ -0,0 +1,25 @@
1
+ flowgraph/__init__.py,sha256=Uhhd9AenUsWYKcisXTq-37rr0foMdM2UTbb5QlPxcsw,309
2
+ flowgraph/ai_proxy.py,sha256=1ilSEhSZM9k_aolvoszk7UbfTKroRKtxASsnNIb43d8,5718
3
+ flowgraph/cli.py,sha256=vMQhhBqWlzzQcrW6W7kOIf9yIR8T25syIn-_n4tRrhk,7247
4
+ flowgraph/config.py,sha256=jNPbD9035vplcjxgnolSimz9lvW7Xs5E_On3DUG8LSw,4103
5
+ flowgraph/keys.py,sha256=YzRN50vLrrGRDa4g5R8LKJXLn5-_O6gf3llREpfRxXc,3531
6
+ flowgraph/providers.py,sha256=3gy0zZ1Trdty2Zf8Nohy0sretvE8DcWvFCJI02xQwoE,2854
7
+ flowgraph/runtime_config.py,sha256=KHqCgKzXMEFIYubyEI2pOb6BhZCV88IGgmdYxM1PNcA,1125
8
+ flowgraph/security.py,sha256=lcqKRysA5NoFHVg7gS2mbGrGM8XL15RReMHQYglyjZ0,11187
9
+ flowgraph/server.py,sha256=qx457Egvvcix7h6vocsxZCeGubwtLeLfr3ybXJIAb-c,4169
10
+ flowgraph/update_check.py,sha256=3wgVTHIwt6WMAQnQLxeh5NfVtBXakyZCAX5-PpFlETE,3762
11
+ flowgraph/_static/_headers,sha256=cmOyww5lRS1Z8w2O6wiZjrpyxp33tc2CdqsibZb4hPs,928
12
+ flowgraph/_static/favicon.svg,sha256=YbyaFh3lgkgojmkFQl1xgPBiTChlAHuX12P9rBIEOmY,9522
13
+ flowgraph/_static/icons.svg,sha256=tF-lBhlc_N70BrqfDHezbdwafCJAQJJuxwq8L96nuTo,5031
14
+ flowgraph/_static/index.html,sha256=kMrXQIA0FoEPmfZgZiaVFhXolAuDWRe0xzLYDhIp0Og,588
15
+ flowgraph/_static/assets/JsonCodeEditor-CBMWkoPU.js,sha256=4DaslSm9-DGkLjwkW8nBx0KTE0gy1MliYTQCLlSdR7M,425248
16
+ flowgraph/_static/assets/index-BE9FlCos.css,sha256=TGkndYbWTDsGCUT7slQAGKijdPm82ToRAwckK-K2710,101924
17
+ flowgraph/_static/assets/index-SiLO3vOy.js,sha256=RAJlyg65El-9_Zzctnf8nQv4IOGW1g3Gnz0VDEhXRAU,2466100
18
+ flowgraph/_static/assets/pdf-B_9Q7Dif.js,sha256=cQc6BUyoLXNJSXYcWQx5dyUR55AMx-8v4g1eLciX1JY,330039
19
+ flowgraph/_static/assets/pdf.worker.min-0p99Cwul.js,sha256=T6e89-gp6ttTvgPHTEVUTIBt6muWufonUckbrRlqZDg,90
20
+ flowgraph/_static/assets/pdf.worker.min-yatZIOMy.mjs,sha256=G6oYRMicgKWyeXyRbnWrKSVL5G2OnLU8tjZNeq2EvjY,1375838
21
+ flowgraphapp-0.1.1.dist-info/METADATA,sha256=h1Kbc6BWahctVocp8vEIeMEuk3UdkMmn5Ej5a4X5OmA,4619
22
+ flowgraphapp-0.1.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
23
+ flowgraphapp-0.1.1.dist-info/entry_points.txt,sha256=Q5JhUIRD3j94Lg8tJFPeN6Rhn0roW3GzKF761hseDlU,49
24
+ flowgraphapp-0.1.1.dist-info/licenses/LICENSE,sha256=JdzzOu6vvblaVZfl3KYyd6Qvbfm39m8EjV3xSL2J8Hw,1022
25
+ flowgraphapp-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ flowgraph = flowgraph.cli:main
@@ -0,0 +1,18 @@
1
+ FlowGraph — Proprietary License
2
+ Copyright (c) 2026 Naveen. All rights reserved.
3
+
4
+ This software and its source code (the "Software") are the confidential and
5
+ proprietary property of the copyright holder. No license, right, or permission
6
+ is granted to any person to use, copy, modify, merge, publish, distribute,
7
+ sublicense, sell, or create derivative works of the Software, in whole or in
8
+ part, without the prior written consent of the copyright holder.
9
+
10
+ Unauthorized copying, distribution, or use of the Software, via any medium, is
11
+ strictly prohibited.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.