nucli 0.5.0__tar.gz → 0.5.2__tar.gz

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.
@@ -201,8 +201,11 @@ lib*.so.*
201
201
  # syncthing
202
202
  .stfolder
203
203
 
204
- # nudle UI (vite / node)
204
+ # ts workspace (pkgs/ts): node deps and vite output are both built, never tracked
205
205
  node_modules/
206
- !packages/nustd/src/nu/ui/web/nudle/dist/
207
- packages/nustd/src/nu/ui/web/nudle/dist/*
208
- !packages/nustd/src/nu/ui/web/nudle/dist/.gitkeep
206
+
207
+ # The nudle wheel's dev bridge. A symlink to pkgs/ts/nudle/dist, so an editable
208
+ # install resolves `nudle.__path__[0] / "build"` without a wheel build. It is a
209
+ # symlink, not a directory, so `build/` above does not catch it -- but say so
210
+ # explicitly rather than leaning on that.
211
+ !pkgs/nudle/src/nudle/build
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: nucli
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: The `nu` command line: doctor, demos, telemetry. Ships alongside the nucore kernel and the nustd fabrics.
5
5
  Project-URL: Repository, https://github.com/nustackdev/nu
6
6
  Author-email: Gor Arakelyan <gorarkln@gmail.com>
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Requires-Python: >=3.10
18
18
  Requires-Dist: click>=8.0
19
- Requires-Dist: nustd>=0.5.0
19
+ Requires-Dist: nustd>=0.5.2
20
20
  Requires-Dist: rich-click>=1.6
21
21
  Requires-Dist: rich>=10.7
22
22
  Description-Content-Type: text/markdown
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nucli"
7
- version = "0.5.0"
7
+ version = "0.5.2"
8
8
  description = "The `nu` command line: doctor, demos, telemetry. Ships alongside the nucore kernel and the nustd fabrics."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -15,7 +15,7 @@ requires-python = ">=3.10"
15
15
  # than the bare kernel because the packaged demos (`nu demo movies`) run on
16
16
  # `nustd.ui` and `nustd.kv` at runtime.
17
17
  dependencies = [
18
- "nustd>=0.5.0",
18
+ "nustd>=0.5.2",
19
19
  "click>=8.0",
20
20
  "rich>=10.7",
21
21
  "rich-click>=1.6",
@@ -67,6 +67,6 @@ def demo(name: str | None) -> None:
67
67
  try:
68
68
  runpy.run_path(str(found[name]), run_name="__main__")
69
69
  except KeyboardInterrupt:
70
- # Ctrl+C during a demo: nudle already printed its stopped banner;
71
- # don't let click surface its default "Aborted!" line on top of it.
70
+ # Ctrl+C during a demo: the ui server already printed its stopped
71
+ # banner; don't let click surface "Aborted!" on top of it.
72
72
  pass
@@ -14,18 +14,23 @@ from nu._config.branding import BLUE, PURPLE
14
14
  from nucli._meta import nu_version
15
15
 
16
16
 
17
- # Fabric extras (as declared in packages/nustd/pyproject.toml) and the import
18
- # that proves they resolve. The backends live in the `nustd` distribution;
19
- # this kernel-side command only probes for them, it never imports the fabric.
20
- _FABRICS: dict[str, str] = {
21
- "kv": "virtuals",
22
- "mem": "janus",
23
- "ui": "nudle",
24
- "cluster": "ray",
25
- "proxy": "invisibles",
26
- "http": "httpx",
27
- "llm": "httpx",
28
- "cc": "claude_agent_sdk",
17
+ # Fabric extras (as declared in pkgs/nustd/pyproject.toml) and the imports
18
+ # that prove they resolve. The backends live in the `nustd` distribution; this
19
+ # kernel-side command only probes for them, it never imports the fabric.
20
+ #
21
+ # Everything an extra imports at module scope belongs here, or the row goes
22
+ # green on an install that cannot import. `ui` reaches `nudle` lazily, from the
23
+ # static mount, and it is probed anyway: without it the browser gets no bundle.
24
+ _FABRICS: dict[str, tuple[str, ...]] = {
25
+ "kv": ("virtuals",),
26
+ "mem": ("janus",),
27
+ "ws_server": ("fastapi", "uvicorn", "watchfiles"),
28
+ "ui": ("fastapi", "uvicorn", "msgpack", "watchfiles", "nudle"),
29
+ "cluster": ("ray",),
30
+ "proxy": ("invisibles",),
31
+ "http": ("httpx",),
32
+ "llm": ("httpx",),
33
+ "cc": ("claude_agent_sdk",),
29
34
  }
30
35
 
31
36
 
@@ -45,13 +50,15 @@ def doctor() -> None:
45
50
  table.add_column("fabric", style="bold")
46
51
  table.add_column("status")
47
52
  table.add_column("install", style="dim")
48
- for name, probe in _FABRICS.items():
49
- if importlib.util.find_spec(probe) is not None:
53
+ for name, probes in _FABRICS.items():
54
+ if all(importlib.util.find_spec(probe) is not None for probe in probes):
50
55
  table.add_row(name, Text("● ok", style="green"), "")
51
56
  else:
52
57
  table.add_row(
53
58
  name,
54
59
  Text("○ missing", style="yellow"),
55
- f"pip install 'nustd[{name}]'",
60
+ # Text, not a bare str: rich reads `[ui]` in a plain string as
61
+ # a style tag and eats it, leaving "pip install 'nustd'".
62
+ Text(f"pip install 'nustd[{name}]'"),
56
63
  )
57
64
  console.print(table)
@@ -66,21 +66,23 @@ class App(nustd.ui.Index):
66
66
  home = Dashboard.slot("/")
67
67
 
68
68
 
69
+ # reactive wire: whenever `value` changes, mirror it into `count`
70
+ ui = nu.ReactForever(
71
+ Counter.value.on_change(),
72
+ App.home.count.set_value(nu.str(Counter.value)),
73
+ )
74
+
75
+ # updater: tick `value` up once a second, forever
76
+ tick = nu.IfDo(Counter.value.missing(), Counter.value.set(0)) >> nu.ForeverDo(
77
+ Counter.value.inc() >> nu.Delay(1.0),
78
+ )
79
+
80
+ # assemble: rocksdb-backed, one live arm of `ui` per open browser tab
69
81
  app = nu.With(
70
82
  nustd.kv.rocksdb_navigator(str(_DB)),
71
- nustd.ui.server(
72
- nustd.kv.auto_flow_atomic(
73
- nu.ReactForever(
74
- Counter.value.on_change(),
75
- App.home.count.set_value(nu.str(Counter.value)),
76
- ),
77
- ),
78
- ),
79
- body=nustd.kv.auto_flow_atomic(
80
- nu.IfDo(Counter.value.missing(), Counter.value.set(0))
81
- >> nu.ForeverDo(
82
- Counter.value.inc() >> nu.Delay(1.0),
83
- )
83
+ body=nu.ParallelAsync(
84
+ nustd.ui.serve(App, nustd.kv.auto_flow_atomic(ui)),
85
+ nustd.kv.auto_flow_atomic(tick),
84
86
  ),
85
87
  )
86
88
 
@@ -468,8 +468,10 @@ ui = (
468
468
 
469
469
  app = nu.With(
470
470
  nustd.kv.rocksdb_navigator(str(_DB)),
471
- nustd.ui.server(nustd.kv.auto_flow_atomic(ui)),
472
- body=nustd.kv.auto_flow_atomic(init >> nu.ForeverDo(nu.Delay(3600))),
471
+ body=nu.ParallelAsync(
472
+ nustd.ui.serve(App, nustd.kv.auto_flow_atomic(ui)),
473
+ nustd.kv.auto_flow_atomic(init),
474
+ ),
473
475
  )
474
476
 
475
477
 
@@ -83,8 +83,10 @@ feed = State.cursor.init(0) >> nu.ForeverDo(
83
83
  # assemble: rocksdb-backed, served over the browser
84
84
  app = nu.With(
85
85
  nustd.kv.rocksdb_navigator(str(_DB)),
86
- nustd.ui.server(nustd.kv.auto_flow_atomic(ui)),
87
- body=nustd.kv.auto_flow_atomic(feed),
86
+ body=nu.ParallelAsync(
87
+ nustd.ui.serve(App, nustd.kv.auto_flow_atomic(ui)),
88
+ nustd.kv.auto_flow_atomic(feed),
89
+ ),
88
90
  )
89
91
 
90
92
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes