nuspace 0.1.0__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.
Files changed (133) hide show
  1. nuspace-0.1.0/.github/workflows/publish-nuspace-ui.yml +119 -0
  2. nuspace-0.1.0/.github/workflows/publish-nuspace.yml +134 -0
  3. nuspace-0.1.0/.gitignore +99 -0
  4. nuspace-0.1.0/.pre-commit-config.yaml +38 -0
  5. nuspace-0.1.0/CHANGELOG.md +74 -0
  6. nuspace-0.1.0/LICENSE.md +667 -0
  7. nuspace-0.1.0/Makefile +135 -0
  8. nuspace-0.1.0/PKG-INFO +38 -0
  9. nuspace-0.1.0/README.md +10 -0
  10. nuspace-0.1.0/examples/apps.py +102 -0
  11. nuspace-0.1.0/examples/pages.py +181 -0
  12. nuspace-0.1.0/examples/web.py +69 -0
  13. nuspace-0.1.0/pyproject.toml +195 -0
  14. nuspace-0.1.0/src/nuspace/__init__.py +40 -0
  15. nuspace-0.1.0/src/nuspace/_root.py +34 -0
  16. nuspace-0.1.0/src/nuspace/apps/__init__.py +75 -0
  17. nuspace-0.1.0/src/nuspace/apps/ops.py +280 -0
  18. nuspace-0.1.0/src/nuspace/apps/runner.py +250 -0
  19. nuspace-0.1.0/src/nuspace/apps/shapes.py +50 -0
  20. nuspace-0.1.0/src/nuspace/cli/__init__.py +6 -0
  21. nuspace-0.1.0/src/nuspace/cli/__main__.py +7 -0
  22. nuspace-0.1.0/src/nuspace/cli/_meta.py +12 -0
  23. nuspace-0.1.0/src/nuspace/cli/main.py +35 -0
  24. nuspace-0.1.0/src/nuspace/core/__init__.py +18 -0
  25. nuspace-0.1.0/src/nuspace/core/fields.py +184 -0
  26. nuspace-0.1.0/src/nuspace/core/host.py +255 -0
  27. nuspace-0.1.0/src/nuspace/core/ids.py +30 -0
  28. nuspace-0.1.0/src/nuspace/core/session.py +125 -0
  29. nuspace-0.1.0/src/nuspace/core/shapes.py +56 -0
  30. nuspace-0.1.0/src/nuspace/core/tpl.py +243 -0
  31. nuspace-0.1.0/src/nuspace/pages/__init__.py +101 -0
  32. nuspace-0.1.0/src/nuspace/pages/ops.py +510 -0
  33. nuspace-0.1.0/src/nuspace/pages/runner.py +422 -0
  34. nuspace-0.1.0/src/nuspace/pages/shapes.py +111 -0
  35. nuspace-0.1.0/src/nuspace/web/__init__.py +75 -0
  36. nuspace-0.1.0/src/nuspace/web/apps/__init__.py +18 -0
  37. nuspace-0.1.0/src/nuspace/web/apps/driver.py +176 -0
  38. nuspace-0.1.0/src/nuspace/web/apps/ref.py +113 -0
  39. nuspace-0.1.0/src/nuspace/web/arms.py +103 -0
  40. nuspace-0.1.0/src/nuspace/web/lens/__init__.py +22 -0
  41. nuspace-0.1.0/src/nuspace/web/lens/driver.py +98 -0
  42. nuspace-0.1.0/src/nuspace/web/lens/ref.py +73 -0
  43. nuspace-0.1.0/src/nuspace/web/lens/reflect.py +371 -0
  44. nuspace-0.1.0/src/nuspace/web/nav.py +74 -0
  45. nuspace-0.1.0/src/nuspace/web/pages/__init__.py +21 -0
  46. nuspace-0.1.0/src/nuspace/web/pages/driver.py +295 -0
  47. nuspace-0.1.0/src/nuspace/web/pages/ref.py +170 -0
  48. nuspace-0.1.0/src/nuspace/web/pages/session.py +170 -0
  49. nuspace-0.1.0/src/nuspace/web/serve/__init__.py +33 -0
  50. nuspace-0.1.0/src/nuspace/web/serve/app.py +150 -0
  51. nuspace-0.1.0/src/nuspace/web/serve/fabric.py +186 -0
  52. nuspace-0.1.0/src/nuspace/web/serve/session.py +180 -0
  53. nuspace-0.1.0/src/nuspace/web/serve/shell.py +216 -0
  54. nuspace-0.1.0/src/nuspace/web/space.py +199 -0
  55. nuspace-0.1.0/src/nuspace/web/ui/.gitignore +26 -0
  56. nuspace-0.1.0/src/nuspace/web/ui/biome.json +63 -0
  57. nuspace-0.1.0/src/nuspace/web/ui/index.html +12 -0
  58. nuspace-0.1.0/src/nuspace/web/ui/package-lock.json +7678 -0
  59. nuspace-0.1.0/src/nuspace/web/ui/package.json +47 -0
  60. nuspace-0.1.0/src/nuspace/web/ui/pyproject.toml +20 -0
  61. nuspace-0.1.0/src/nuspace/web/ui/src/App.tsx +136 -0
  62. nuspace-0.1.0/src/nuspace/web/ui/src/app/connect.ts +90 -0
  63. nuspace-0.1.0/src/nuspace/web/ui/src/app/router.ts +123 -0
  64. nuspace-0.1.0/src/nuspace/web/ui/src/app/theme.ts +77 -0
  65. nuspace-0.1.0/src/nuspace/web/ui/src/components/index.ts +24 -0
  66. nuspace-0.1.0/src/nuspace/web/ui/src/components/page-header.tsx +275 -0
  67. nuspace-0.1.0/src/nuspace/web/ui/src/components/rail/header.tsx +43 -0
  68. nuspace-0.1.0/src/nuspace/web/ui/src/components/rail/index.ts +24 -0
  69. nuspace-0.1.0/src/nuspace/web/ui/src/components/rail/roving-focus.ts +90 -0
  70. nuspace-0.1.0/src/nuspace/web/ui/src/components/rail/row-input.tsx +59 -0
  71. nuspace-0.1.0/src/nuspace/web/ui/src/components/rail/row.tsx +131 -0
  72. nuspace-0.1.0/src/nuspace/web/ui/src/components/section-status-dot.tsx +108 -0
  73. nuspace-0.1.0/src/nuspace/web/ui/src/design/apps.ts +89 -0
  74. nuspace-0.1.0/src/nuspace/web/ui/src/design/document.ts +352 -0
  75. nuspace-0.1.0/src/nuspace/web/ui/src/design/header.ts +150 -0
  76. nuspace-0.1.0/src/nuspace/web/ui/src/design/index.ts +42 -0
  77. nuspace-0.1.0/src/nuspace/web/ui/src/design/lens.css +107 -0
  78. nuspace-0.1.0/src/nuspace/web/ui/src/design/lens.ts +259 -0
  79. nuspace-0.1.0/src/nuspace/web/ui/src/design/rail.ts +227 -0
  80. nuspace-0.1.0/src/nuspace/web/ui/src/design/section-status.ts +155 -0
  81. nuspace-0.1.0/src/nuspace/web/ui/src/design/shell.ts +57 -0
  82. nuspace-0.1.0/src/nuspace/web/ui/src/design/tokens.css +176 -0
  83. nuspace-0.1.0/src/nuspace/web/ui/src/index.css +40 -0
  84. nuspace-0.1.0/src/nuspace/web/ui/src/main.tsx +41 -0
  85. nuspace-0.1.0/src/nuspace/web/ui/src/refs/apps/Rail.tsx +316 -0
  86. nuspace-0.1.0/src/nuspace/web/ui/src/refs/apps/Source.tsx +142 -0
  87. nuspace-0.1.0/src/nuspace/web/ui/src/refs/apps/apps.tsx +225 -0
  88. nuspace-0.1.0/src/nuspace/web/ui/src/refs/apps/ops.ts +34 -0
  89. nuspace-0.1.0/src/nuspace/web/ui/src/refs/apps/slice.ts +129 -0
  90. nuspace-0.1.0/src/nuspace/web/ui/src/refs/apps/types.ts +69 -0
  91. nuspace-0.1.0/src/nuspace/web/ui/src/refs/lens/lens.tsx +633 -0
  92. nuspace-0.1.0/src/nuspace/web/ui/src/refs/lens/types.ts +90 -0
  93. nuspace-0.1.0/src/nuspace/web/ui/src/refs/nav/nav.ts +76 -0
  94. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/Canvas.tsx +847 -0
  95. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/Code.tsx +203 -0
  96. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/Program.tsx +186 -0
  97. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/ProseRef.test.tsx +206 -0
  98. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/ProseRef.tsx +549 -0
  99. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/Rail.tsx +581 -0
  100. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/Slash.tsx +260 -0
  101. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/monaco-impl.ts +92 -0
  102. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/monaco.ts +50 -0
  103. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/ops.ts +71 -0
  104. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/pages.tsx +162 -0
  105. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/prose.ts +68 -0
  106. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/slice.ts +317 -0
  107. nuspace-0.1.0/src/nuspace/web/ui/src/refs/pages/types.ts +230 -0
  108. nuspace-0.1.0/src/nuspace/web/ui/src/refs/register.ts +8 -0
  109. nuspace-0.1.0/src/nuspace/web/ui/src/vite-env.d.ts +5 -0
  110. nuspace-0.1.0/src/nuspace/web/ui/tsconfig.app.json +31 -0
  111. nuspace-0.1.0/src/nuspace/web/ui/tsconfig.json +10 -0
  112. nuspace-0.1.0/src/nuspace/web/ui/tsconfig.node.json +24 -0
  113. nuspace-0.1.0/src/nuspace/web/ui/vite.config.ts +55 -0
  114. nuspace-0.1.0/src/nuspace/web/ui/vitest.config.ts +44 -0
  115. nuspace-0.1.0/src/nuspace/web/wire.py +47 -0
  116. nuspace-0.1.0/tests/nuspace/apps/__init__.py +0 -0
  117. nuspace-0.1.0/tests/nuspace/apps/conftest.py +127 -0
  118. nuspace-0.1.0/tests/nuspace/apps/test_changed_key.py +81 -0
  119. nuspace-0.1.0/tests/nuspace/apps/test_lifecycle.py +209 -0
  120. nuspace-0.1.0/tests/nuspace/apps/test_ops.py +190 -0
  121. nuspace-0.1.0/tests/nuspace/pages/__init__.py +0 -0
  122. nuspace-0.1.0/tests/nuspace/pages/conftest.py +180 -0
  123. nuspace-0.1.0/tests/nuspace/pages/test_invariant.py +97 -0
  124. nuspace-0.1.0/tests/nuspace/pages/test_lifecycle.py +228 -0
  125. nuspace-0.1.0/tests/nuspace/pages/test_ops.py +435 -0
  126. nuspace-0.1.0/tests/nuspace/test_imports.py +93 -0
  127. nuspace-0.1.0/tests/nuspace/web/__init__.py +0 -0
  128. nuspace-0.1.0/tests/nuspace/web/test_apps_driver.py +315 -0
  129. nuspace-0.1.0/tests/nuspace/web/test_lens_driver.py +330 -0
  130. nuspace-0.1.0/tests/nuspace/web/test_lens_reflect.py +164 -0
  131. nuspace-0.1.0/tests/nuspace/web/test_pages_driver.py +340 -0
  132. nuspace-0.1.0/tests/nuspace/web/test_serve.py +112 -0
  133. nuspace-0.1.0/tests/nuspace/web/test_supervised.py +415 -0
@@ -0,0 +1,119 @@
1
+ # Publishes the `nuspace-ui` wheel to PyPI on a tag push like `nuspace-ui@0.1.0`.
2
+ # Manual "Run workflow" dispatch builds but does NOT publish.
3
+ #
4
+ # The nuspace-ui wheel is nothing but the compiled vite SPA, force-included at
5
+ # the wheel path `nuspace_ui/build/`. It carries no python source and no
6
+ # dependencies. The runtime locates it with `import nuspace_ui` -- see
7
+ # `_bundled_static()` in src/nuspace/web/serve/app.py -- and skips the static
8
+ # mount entirely if it is not installed.
9
+ #
10
+ # Keeping the bundle in its own distribution is the point: PyPI caps project
11
+ # size, and a compiled SPA rebuilt on every UI tweak would burn through the
12
+ # `nuspace` project's quota. Here it churns on its own budget.
13
+ #
14
+ # Setup once (PyPI trusted publisher / OIDC, no secrets):
15
+ # pypi.org -> account -> Publishing -> Add pending publisher
16
+ # PyPI project name: nuspace-ui
17
+ # Owner: nustackdev
18
+ # Repository name: nuspace
19
+ # Workflow name: publish-nuspace-ui.yml
20
+ # Environment name: (leave blank)
21
+ #
22
+ # Release flow:
23
+ # 1. Bump `version` in both `src/nuspace/web/ui/pyproject.toml` and
24
+ # `src/nuspace/web/ui/package.json` (keep them equal).
25
+ # 2. Commit and push to main.
26
+ # 3. `git tag nuspace-ui@X.Y.Z && git push origin nuspace-ui@X.Y.Z`.
27
+ name: Publish nuspace-ui to PyPI
28
+
29
+ on:
30
+ push:
31
+ tags: ["nuspace-ui@*"]
32
+ workflow_dispatch:
33
+
34
+ permissions:
35
+ contents: read
36
+ id-token: write # PyPI trusted publishing (OIDC)
37
+
38
+ concurrency:
39
+ group: publish-nuspace-ui
40
+ cancel-in-progress: false
41
+
42
+ env:
43
+ UI_DIR: src/nuspace/web/ui
44
+
45
+ jobs:
46
+ publish:
47
+ runs-on: ubuntu-latest
48
+ timeout-minutes: 15
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - uses: actions/setup-node@v4
53
+ with:
54
+ node-version: 24
55
+ cache: npm
56
+ cache-dependency-path: src/nuspace/web/ui/package-lock.json
57
+
58
+ - uses: actions/setup-python@v5
59
+ with:
60
+ python-version: "3.12"
61
+
62
+ - name: install uv
63
+ uses: astral-sh/setup-uv@v5
64
+
65
+ # Both files carry the version; a tag that matches one and not the other
66
+ # would ship a wheel whose contents disagree with its metadata.
67
+ - name: verify tag matches pyproject.toml and package.json
68
+ if: startsWith(github.ref, 'refs/tags/nuspace-ui@')
69
+ working-directory: ${{ env.UI_DIR }}
70
+ run: |
71
+ TAG_VERSION="${GITHUB_REF#refs/tags/nuspace-ui@}"
72
+ PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
73
+ NPM_VERSION=$(node -p "require('./package.json').version")
74
+ if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
75
+ echo "tag nuspace-ui@$TAG_VERSION does not match pyproject.toml version $PKG_VERSION"
76
+ exit 1
77
+ fi
78
+ if [ "$TAG_VERSION" != "$NPM_VERSION" ]; then
79
+ echo "tag nuspace-ui@$TAG_VERSION does not match package.json version $NPM_VERSION"
80
+ exit 1
81
+ fi
82
+
83
+ - name: install js deps
84
+ working-directory: ${{ env.UI_DIR }}
85
+ run: npm ci
86
+
87
+ - name: typecheck
88
+ working-directory: ${{ env.UI_DIR }}
89
+ run: npm run typecheck
90
+
91
+ # `npm run build` is `tsc -b && vite build` -- output lands in dist/,
92
+ # which the hatch force-include maps to `nuspace_ui/build/` in the wheel.
93
+ - name: build bundle
94
+ working-directory: ${{ env.UI_DIR }}
95
+ run: npm run build
96
+
97
+ - name: fail if the bundle is empty
98
+ working-directory: ${{ env.UI_DIR }}
99
+ run: |
100
+ if [ ! -f dist/index.html ]; then
101
+ echo "vite build produced no dist/index.html -- refusing to ship an empty bundle"
102
+ exit 1
103
+ fi
104
+ ls -la dist
105
+
106
+ # --wheel skips the sdist step: an sdist would strip `dist/` (gitignored)
107
+ # and the wheel-from-sdist path would fail the force-include lookup.
108
+ # --out-dir keeps the wheel out of `dist/`, which IS the vite output we
109
+ # force-include into it.
110
+ - name: build wheel
111
+ working-directory: ${{ env.UI_DIR }}
112
+ run: uv build --wheel --out-dir wheel-dist
113
+
114
+ - name: publish
115
+ if: startsWith(github.ref, 'refs/tags/nuspace-ui@')
116
+ uses: pypa/gh-action-pypi-publish@release/v1
117
+ with:
118
+ packages-dir: src/nuspace/web/ui/wheel-dist
119
+ skip-existing: true
@@ -0,0 +1,134 @@
1
+ # Publishes the `nuspace` distribution to PyPI on a tag push like `nuspace@0.1.0`.
2
+ # Manual "Run workflow" dispatch builds only, unless you tick `publish`.
3
+ #
4
+ # `nuspace` tags own release semantics for the repo -- this workflow also
5
+ # creates a GitHub Release attached to the tag. The sibling `nuspace-ui` wheel
6
+ # has its own tag but does not cut a release.
7
+ #
8
+ # Setup once (PyPI trusted publisher / OIDC, no secrets):
9
+ # pypi.org -> account -> Publishing -> Add pending publisher
10
+ # PyPI project name: nuspace
11
+ # Owner: nustackdev
12
+ # Repository name: nuspace
13
+ # Workflow name: publish-nuspace.yml
14
+ # Environment name: (leave blank)
15
+ #
16
+ # Two distributions ship from this repo, on independent tags:
17
+ # . -> nuspace (the runtime + the `nuspace` command)
18
+ # src/nuspace/web/ui -> nuspace-ui (the compiled vite bundle)
19
+ #
20
+ # They version independently. `nuspace` hard-depends on `nuspace-ui>=X.Y.Z`, so
21
+ # a python release can require a newer bundle, but a bundle-only fix ships on
22
+ # its own tag without republishing this wheel.
23
+ #
24
+ # The wheel deliberately excludes `src/nuspace/web/ui/**` (see the hatch config
25
+ # in pyproject.toml). The compiled assets live in the nuspace-ui wheel and are
26
+ # found at runtime by `import nuspace_ui` -- see `_bundled_static()` in
27
+ # src/nuspace/web/serve/app.py. So this build needs no node toolchain, even
28
+ # though an install always pulls the bundle.
29
+ #
30
+ # Ordering on a coordinated release: push the `nuspace-ui@` tag first, so the
31
+ # bundle is on the index before the wheel that requires it.
32
+ #
33
+ # Release flow:
34
+ # 1. Bump `version` in `pyproject.toml`.
35
+ # 2. Rename the CHANGELOG's `Unreleased` heading to the new version + date,
36
+ # and update the package list at the top.
37
+ # 3. Commit and push to main.
38
+ # 4. `git tag nuspace@X.Y.Z && git push origin nuspace@X.Y.Z`.
39
+ name: Publish nuspace to PyPI
40
+
41
+ on:
42
+ push:
43
+ tags: ["nuspace@*"]
44
+ workflow_dispatch:
45
+ inputs:
46
+ publish:
47
+ description: "Publish to PyPI (otherwise build only)"
48
+ type: boolean
49
+ default: false
50
+
51
+ permissions:
52
+ contents: write # needed to create the GitHub Release on tag push
53
+ id-token: write # needed for PyPI trusted publishing (OIDC)
54
+
55
+ concurrency:
56
+ group: publish-nuspace
57
+ cancel-in-progress: false
58
+
59
+ jobs:
60
+ publish:
61
+ runs-on: ubuntu-latest
62
+ timeout-minutes: 10
63
+ steps:
64
+ - uses: actions/checkout@v4
65
+ with:
66
+ fetch-depth: 0
67
+
68
+ - uses: actions/setup-python@v5
69
+ with:
70
+ python-version: "3.12"
71
+
72
+ - name: install uv
73
+ uses: astral-sh/setup-uv@v5
74
+
75
+ - name: verify tag matches pyproject.toml version
76
+ if: startsWith(github.ref, 'refs/tags/nuspace@')
77
+ run: |
78
+ TAG_VERSION="${GITHUB_REF#refs/tags/nuspace@}"
79
+ PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
80
+ if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
81
+ echo "tag nuspace@$TAG_VERSION does not match pyproject.toml version $PKG_VERSION"
82
+ exit 1
83
+ fi
84
+
85
+ # `uv build` would normally resolve the `[tool.uv.sources]` path entries
86
+ # (the local nu / nuagent checkouts next to this repo, absent on CI).
87
+ # Build is metadata-only for a hatchling project, so nothing is resolved
88
+ # and the published wheel carries the plain PyPI requirements.
89
+ - name: build distribution
90
+ run: uv build --out-dir dist
91
+
92
+ # skip-existing keeps this idempotent: a rerun after a partial failure
93
+ # resumes instead of dying on files that already uploaded, and a tag can
94
+ # be pushed after a manual publish to cut the GitHub Release.
95
+ - name: publish nuspace
96
+ if: >-
97
+ startsWith(github.ref, 'refs/tags/nuspace@') || inputs.publish
98
+ uses: pypa/gh-action-pypi-publish@release/v1
99
+ with:
100
+ packages-dir: dist
101
+ skip-existing: true
102
+
103
+ - name: build release notes from CHANGELOG
104
+ if: startsWith(github.ref, 'refs/tags/nuspace@')
105
+ run: |
106
+ VERSION="${GITHUB_REF#refs/tags/nuspace@}"
107
+ PREV=$(git tag -l 'nuspace@*' --sort=-v:refname | grep -v "^nuspace@${VERSION}$" | head -1)
108
+ {
109
+ echo "## Changelog"
110
+ echo
111
+ awk -v ver="$VERSION" '
112
+ $0 ~ "^## "ver"( |$)" {flag=1; next}
113
+ flag && /^## / {exit}
114
+ flag {print}
115
+ ' CHANGELOG.md
116
+ if [ -n "$PREV" ]; then
117
+ echo
118
+ echo "**Full Changelog**: https://github.com/${GITHUB_REPOSITORY}/compare/${PREV}...nuspace@${VERSION}"
119
+ fi
120
+ } > release_notes.md
121
+ cat release_notes.md
122
+
123
+ - name: create github release
124
+ if: startsWith(github.ref, 'refs/tags/nuspace@')
125
+ uses: softprops/action-gh-release@v2
126
+ with:
127
+ name: ${{ github.ref_name }}
128
+ body_path: release_notes.md
129
+ # Explicit extensions, not `dist/**`: uv drops a .gitignore in its
130
+ # output dir and the broad glob uploaded it as `default.gitignore`.
131
+ files: |
132
+ dist/*.whl
133
+ dist/*.tar.gz
134
+ dist/*.attestation
@@ -0,0 +1,99 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ share/python-wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # Installer logs
29
+ pip-log.txt
30
+ pip-delete-this-directory.txt
31
+
32
+ # Unit test / coverage reports
33
+ htmlcov/
34
+ .tox/
35
+ .nox/
36
+ .coverage
37
+ .coverage.*
38
+ .cache
39
+ nosetests.xml
40
+ coverage.xml
41
+ *.cover
42
+ *.py,cover
43
+ .hypothesis/
44
+ .pytest_cache/
45
+ cover/
46
+
47
+ # Environments
48
+ .env
49
+ .venv
50
+ env/
51
+ venv/
52
+ ENV/
53
+ env.bak/
54
+ venv.bak/
55
+
56
+ # uv
57
+ uv.lock
58
+
59
+ # mypy
60
+ .mypy_cache/
61
+ .dmypy.json
62
+ dmypy.json
63
+
64
+ # IDEs
65
+ .idea/
66
+ .vscode/
67
+
68
+ .DS_Store
69
+
70
+ # Profiling
71
+ *.prof
72
+ *.lprof
73
+
74
+ # Benchmarking
75
+ benchmark_results/
76
+ *.benchmark
77
+ *.benchmarks
78
+
79
+ # Ruff
80
+ .ruff_cache/
81
+
82
+ # Misc
83
+ /*playground
84
+ .db*/
85
+ .state*/
86
+ .logs*/
87
+
88
+ # syncthing
89
+ .stfolder
90
+
91
+ # nuspace-ui (vite / node)
92
+ node_modules/
93
+ !src/nuspace/web/ui/dist/
94
+ src/nuspace/web/ui/dist/*
95
+ !src/nuspace/web/ui/dist/.gitkeep
96
+
97
+ *.db/
98
+ # local archive of the v0 prototype (reference only, never edited)
99
+ _archive/
@@ -0,0 +1,38 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.6.0
4
+ hooks:
5
+ - id: check-yaml
6
+ - id: check-toml
7
+ - id: check-json
8
+ - id: check-added-large-files
9
+ args: ['--maxkb=1000']
10
+ - id: check-case-conflict
11
+ - id: check-merge-conflict
12
+ - id: detect-private-key
13
+ - id: end-of-file-fixer
14
+ - id: trailing-whitespace
15
+ - id: mixed-line-ending
16
+ args: ['--fix=lf']
17
+
18
+ - repo: https://github.com/astral-sh/ruff-pre-commit
19
+ rev: v0.13.2
20
+ hooks:
21
+ - id: ruff
22
+ args: [--fix]
23
+ - id: ruff-format
24
+
25
+ default_language_version:
26
+ python: python3.10
27
+
28
+ ci:
29
+ autofix_commit_msg: |
30
+ [pre-commit.ci] auto fixes from pre-commit.com hooks
31
+
32
+ for more information, see https://pre-commit.ci
33
+ autofix_prs: true
34
+ autoupdate_branch: ''
35
+ autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate'
36
+ autoupdate_schedule: weekly
37
+ skip: []
38
+ submodules: false
@@ -0,0 +1,74 @@
1
+ # Changelog
2
+
3
+ ## Packages shipped from this repo
4
+
5
+ - **nuspace** (the runtime, the `nuspace` command) — 0.1.0
6
+ - **nuspace-ui** (the compiled web bundle) — 0.1.0
7
+
8
+ Below is the changelog for **nuspace** - the full commit stream. Newest first.
9
+ The `nuspace-ui` wheel is the same source tree's vite output and is not tracked
10
+ separately here.
11
+
12
+ ## 0.1.0 — 2026-09-14
13
+
14
+ - Add CI/CD: publish-nuspace and publish-nuspace-ui workflows, trusted publishing, tag-driven releases
15
+ - Rename the distribution nuspace-py to nuspace, make nuspace-ui a hard dependency
16
+ - Keep a hot spare worker so navigation skips the spawn
17
+ - Let the page worker follow its own sections instead of respawning
18
+ - Give workers the store's change feed and drop the proxy workaround
19
+ - Run a whole page in one pool worker
20
+ - Run page sections in pool workers with the connection's session proxied in
21
+ - Attach the apps and page supervisors and assemble the space in one tree
22
+ - Add the lens surface: shape reflection as Miller columns
23
+ - Add the apps web surface and compose both drivers into one space
24
+ - Add the web layer: pages ref, nav ref and the reactive driver
25
+ - Bind the reconcile attrs with Let instead of SetCmd
26
+ - Flatten pages onto parent and children relations, drop recursive addressing
27
+ - Add the pages submodule and break the shapes import cycle
28
+ - Organize apps into shapes, ops and runner
29
+ - Replace the runner with a reactive apps driver on nu.mp_pool
30
+ - Add the runner: one Nu tree that dispatches apps onto a worker pool
31
+ - Add a recursive shape slot and runtime-depth addressing
32
+ - Remove the imperative driver layer
33
+ - Make every block a Nu program addressed by tpl
34
+ - Restore the left inset on flat rail rows
35
+ - Extract the shared rail row, header and roving focus into components
36
+ - Unify the section status and spec contracts into one home
37
+ - Decompose the lens surface into interactions over per-op refs
38
+ - Decompose the apps surface into interactions over per-op refs
39
+ - Decompose the pages surface into interactions over per-op refs
40
+ - Restructure the ui project into app, design, components and refs
41
+ - Remove a stray character that broke taste_app import
42
+ - Add the taste app: a nuagent run over the movie shelf
43
+ - Mount Apps in the demo; flatten apps in the probe scripts
44
+ - Build the Apps pillar on a space-lifetime supervisor
45
+ - Add the Movies app to the demo
46
+ - Fix theme color-scheme, banner noise, and the lens cursor on pop
47
+ - Restyle lens on the design system
48
+ - Rebuild the pages rail: layout, reveal model, keyboard
49
+ - Give pages a real masthead
50
+ - Make the demo's port and store env-overridable
51
+ - Rebuild the shell chrome on kit components; add theming
52
+ - Add a biome config for the nuspace ui bundle
53
+ - Replace the prose leaf with a ProseMirror editor
54
+ - Resolve the worker's kv scope from config; add the Ticker demo page
55
+ - Adopt nu.prog for section construction
56
+ - Rebuild pages on an out-of-process section executor
57
+ - Add section path tags in both modes and + text / + llm section templates
58
+ - Fix section mounting: mount only ui refs under the owning section's path prefix
59
+ - Add Pages section: recursive Page shape, PagesRef with nested rail + section canvas, code/display modes
60
+ - Add Apps section: nested Group shape, AppsRef with tree+editor, router depth, CRUD flows
61
+ - Fix LensRef: strip runtime payload mutation; browser owns cursor, server stateless
62
+ - Add nuspace 3-page shell: Apps/Pages/Lens routes, HeaderRef + SidebarRef, LensRef path-as-observable
63
+ - Upgrade nuspace to ui-kit 0.1.3 and use kit's registerRefEntry directly
64
+ - Add LensRef v1: nuspace server + ui split, refs/lens, examples/lens_demo, App.tsx dupe fix
65
+ - Wipe web/ mvp: rm server + block ui; rename ui to shell; scaffold refs/ + nuspace_ui.py entry
66
+ - Fix Space ref read-back: proxy body/tag wiring; add read_probe example
67
+ - Rewrite nuspace core as Nu-dialect: typed Shape refs (Space/App/Page/Section, AppsRef/SectionsRef with .add/.run), examples/{run,seed_direct,seed_via_proxy}.py; gut CLI, drop old primitives/control/app
68
+ - Reorganize src/nuspace/ui/ into src/nuspace/web/{server,ui}; fix tailwind @source path
69
+ - Refactor nuspace to kind-blind: block is just a snippet, mount enumerates ui refs from the term; add editable code mode + update_snippet primitive; empty-block creation
70
+ - Add stat block kind: reactive display of another text block's value
71
+ - Add per-block display/code toggle and + new page / + new block ui actions
72
+ - Add nuspace mvp v0: python host, react spa, kv primitives, cli, text-block snippet load
73
+ - Add dev scaffolding
74
+ - Init nuspace