@signalk/app-dock 1.2.1 → 1.3.0

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.
@@ -1,42 +0,0 @@
1
- # Marks issues labeled "awaiting response" as stale after 30 days of inactivity
2
- # and closes them 30 days after that (60 days total). Issues labeled
3
- # "good first task" or "help wanted" are exempt. Pull requests are never
4
- # touched. The workflow runs daily and can also be triggered manually.
5
- name: Stale issues
6
-
7
- on:
8
- schedule:
9
- - cron: '17 1 * * *'
10
- workflow_dispatch:
11
-
12
- permissions:
13
- contents: read
14
- issues: write
15
-
16
- concurrency:
17
- group: stale
18
- cancel-in-progress: false
19
-
20
- jobs:
21
- stale:
22
- runs-on: ubuntu-latest
23
- timeout-minutes: 10
24
- steps:
25
- - uses: actions/stale@v10
26
- with:
27
- days-before-issue-stale: 30
28
- days-before-issue-close: 30
29
- stale-issue-label: 'stale'
30
- any-of-issue-labels: 'awaiting response'
31
- exempt-issue-labels: 'good first task,help wanted'
32
- stale-issue-message: >
33
- This issue is marked as awaiting a response from the reporter and
34
- has had no activity for 30 days. It will be closed in another 30
35
- days if there is no further update. If the issue is still
36
- relevant, please reply with any missing information.
37
- close-issue-message: >
38
- Closing this issue because it has been stale for 60 days without
39
- a response. Please reopen if this is still relevant.
40
- days-before-pr-stale: -1
41
- days-before-pr-close: -1
42
- operations-per-run: 100
package/.prettierignore DELETED
@@ -1,6 +0,0 @@
1
- node_modules
2
- public/remoteEntry.js
3
- public/540.js
4
- public/805.js
5
- public/main.js
6
- public/540.js.LICENSE.txt
package/.prettierrc DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "semi": false,
3
- "singleQuote": true,
4
- "trailingComma": "none",
5
- "printWidth": 120
6
- }
@@ -1,3 +0,0 @@
1
- {
2
- ".": "1.2.1"
3
- }
package/AGENTS.md DELETED
@@ -1,134 +0,0 @@
1
- # @signalk/app-dock
2
-
3
- A Signal K server plugin plus webapp: a macOS-style dock for switching between Signal K webapps on touch screens. The
4
- dock page holds each app in an iframe, and a double-tap anywhere brings up the dock. User-facing behaviour is documented
5
- in `README.md`; this file covers what a contributor needs to keep intact.
6
-
7
- ## Architecture
8
-
9
- Three surfaces ship together from one package:
10
-
11
- - **`plugin/index.js`**: the server plugin (CommonJS). It holds the schema, seeds the default apps on first start, serves
12
- the dock's HTTP routes, and registers the `environment.mode` PUT handler for the night-mode button.
13
- - **`public/dock.js`, `dock.css`, `index.html`**: the dock itself, served as-is at `/@signalk/app-dock/`. Plain browser
14
- JavaScript with **no build step**: edit and reload.
15
- - **`src/configpanel/`**: the React 19 config panel that the admin UI loads through Webpack Module Federation (keyword
16
- `signalk-plugin-configurator`). `npm run build:config` writes `public/remoteEntry.js` and its chunks.
17
-
18
- `public/config.html` is an older standalone configurator that the schema description links to; the admin UI shows the
19
- React panel.
20
-
21
- ## Rules to keep in mind
22
-
23
- - **Seed once, never rewrite.** `start()` seeds `DEFAULT_APPS` only when the saved `apps` is not an array. An app list
24
- that already exists, even an empty one, is the user's and is never changed.
25
- - **The default app list lives in three places.** `DEFAULT_APPS` in `plugin/index.js`, `NO_ADMIN_DEFAULTS` in
26
- `public/dock.js` (served to visitors the plugin's `/settings` refuses), and the welcome-tour text in
27
- `public/index.html`. Change them together.
28
- - **`savePluginOptions` replaces the whole saved configuration.** Build every save from a complete configuration
29
- (`running ? pluginSettings : savedSettings()`), never from a partial object.
30
- - **Routes must work while the plugin is stopped.** signalk-server registers the router of every loaded plugin, enabled
31
- or not. A handler that needs the configuration reads `app.readPluginOptions()` when `running` is false.
32
- - **Access is opt-in per route.** Routes on `router` are admin-only. `router.access('readonly' | 'readwrite')`
33
- (signalk-server 2.31 and later) opens a route to more users; feature-detect it (`typeof router.access === 'function'`)
34
- so older servers keep working admin-only. `/config` stays admin-only on every server. When access changes, update the
35
- access detection at the top of `dock.js` and the **Access** table in `README.md` with it.
36
- - **`/settings` is readable by every visitor with read access.** Never put credentials or anything secret in it; that
37
- includes app URLs.
38
- - **Taps pass through.** The double-tap listener is passive, never calls `preventDefault()`, and there is no overlay
39
- element. It attaches to the dock document and, recursively, to every same-origin iframe document, so apps that embed
40
- other apps still open the dock.
41
- - **One iframe sandbox string.** `switchToApp()` and the tour's Plugin Config link in `dock.js` create iframes with the
42
- same `sandbox` value; keep them identical. `allow-top-navigation-by-user-activation` is what lets a dock opened inside
43
- a dock break out to the top window (the guard at the top of `dock.js`).
44
- - **Live config reload.** The dock polls the plugin every 5 s. A setting that changes how the dock is built belongs in
45
- `STRUCTURAL_KEYS` in `dock.js` (the page reloads); app-list changes rebuild the dock in place.
46
- - **New settings touch four places:** the schema in `plugin/index.js`, `DEFAULTS` in `dock.js`, the config panel in
47
- `src/configpanel/`, and the **Settings** table in `README.md`.
48
- - **Browser globals are declared.** ESLint lints `dock.js` as a classic script with an explicit globals list in
49
- `eslint.config.js`; add a browser API there when `dock.js` starts using it.
50
-
51
- ## Build output is committed
52
-
53
- `public/remoteEntry.js`, `public/main.js`, `public/540.js`, `public/805.js` and `public/540.js.LICENSE.txt` are Webpack
54
- output and are tracked in git. After changing `src/configpanel/`, run `npm run build:config` and commit the regenerated
55
- files with the source change. `prepublishOnly` rebuilds them at publish time. Prettier and ESLint skip them, and ESLint
56
- also skips `src/`.
57
-
58
- ## Icons
59
-
60
- `public/app-icon.svg` is the source icon: the `signalk.appIcon` shown by the admin UI and the App Store, the favicon,
61
- and the dock's own logo. `public/app-icon-180.png` (apple-touch-icon) is generated from it and
62
- `public/app-icon-maskable.svg` is maintained by hand; see **Icon assets** in `README.md`.
63
-
64
- ## Tests
65
-
66
- `npm test` runs `test/plugin.test.js` with `node:test` against a mock `app` (`createMockApp()`). Cover new routes,
67
- settings and seeding behaviour there. `dock.js` has no automated tests; check dock changes in a browser against a
68
- running server (see **Development** in `README.md`).
69
-
70
- ## Workflow conventions
71
-
72
- This repo is maintained by Dirk Wahrheit.
73
-
74
- - Branch names use **hyphens**, never slashes.
75
- - Angular conventional commits: `<type>(<scope>): <subject>`. PR titles use the same format; the generated release
76
- notes are built from them.
77
- - The PR title's type also picks its section in the release notes. `.github/workflows/label-by-title.yml` labels each
78
- PR when it is opened or its title edited: `feat`/`perf` → `enhancement` (🚀 Features), `fix` → `bug` (🐛 Fixes),
79
- `docs` → `documentation` (📖 Documentation), `build`/`ci`/`test`/`chore`/`refactor`/`style` → `skip-changelog`
80
- (left out). Any other type lands under Other. A label set by hand stays until the title is next edited. Keep the
81
- workflow and `.github/release.yml` naming the same labels.
82
- - One logical change per commit.
83
- - No `Co-Authored-By` lines. No "Generated with Claude Code" attribution.
84
- - Never commit directly to `main`. Every change goes through a PR.
85
- - PR descriptions: no checkboxes. "Tested" lists what actually ran, not what was planned.
86
- - No hand-written CHANGELOG; GitHub Releases carry generated notes.
87
-
88
- ### Before opening a PR
89
-
90
- ```bash
91
- npm run format # prettier --write + eslint --fix
92
- npm run lint
93
- npm test
94
- npm run build:config # only when src/configpanel/ changed; commit the output
95
- ```
96
-
97
- CI (`.github/workflows/ci.yml`) calls signalk-server's shared `plugin-ci.yml`: install, `npm test`, plugin lifecycle
98
- and schema checks, npm-pack contents, and an App Store style `--ignore-scripts` install. It does **not** run Prettier or
99
- ESLint, so run them locally.
100
-
101
- ### Releases
102
-
103
- Releases are cut by release-please. Every releasable push to `main` updates a standing release PR titled
104
- `chore(release): X.Y.Z` that bumps `version` in `package.json` and `package-lock.json`. Merging it creates the tag and
105
- the GitHub Release, and `.github/workflows/release-please.yml` then dispatches `release_on_tag.yml` on the tag, which
106
- publishes to npm with provenance (OIDC trusted publishing, no token).
107
-
108
- - **The version follows the commits:** `feat` → minor, `fix`, `perf` and `revert` → patch, `!` or a
109
- `BREAKING CHANGE:` footer → major. A `Release-As: X.Y.Z` footer overrides it. Do not bump the version in an ordinary
110
- PR.
111
- - **A push with nothing releasable leaves the release PR alone.** The `gate` job in `release-please.yml` decides what
112
- counts; its comment lists the cases. Revert with a conventional `revert:` subject, since release-please ignores
113
- GitHub's `Revert "…"`. Change the gate's last alternative together with `pull-request-title-pattern` in
114
- `release-please-config.json`, or the release PR's merge never creates a tag.
115
- - **Merge the release PR once it lists your change.** release-please refreshes it a moment after each merge; a
116
- release PR merged before that still ships the change (the tag is on top of it) but its notes leave it out.
117
- - **Pre-releases are cut by hand:** a `chore(release): X.Y.Z-beta.N` PR, then an annotated tag `vX.Y.Z-beta.N` pushed
118
- on its merge commit. `release_on_tag.yml` creates their Release itself and publishes under the npm dist-tag `alpha`,
119
- `beta` or `rc` that the tag contains.
120
-
121
- ## File layout
122
-
123
- | Path | Purpose |
124
- | ----------------------------- | ------------------------------------------------------------------------------------- |
125
- | `plugin/index.js` | Plugin entry: schema, default-app seeding, routes, night-mode PUT handler. |
126
- | `public/index.html` | Dock page: idle screen, dock, backdrop, loading overlay, welcome tour. |
127
- | `public/dock.js` | Dock logic: access detection, config loading and polling, iframes, double-tap, dock. |
128
- | `public/dock.css` | Dock styling, magnification, positions. |
129
- | `public/manifest.webmanifest` | PWA manifest for Add to Home Screen. |
130
- | `public/config.html` | Older standalone configurator. |
131
- | `src/configpanel/` | React config panel for the admin UI (Module Federation remote). |
132
- | `webpack.config.js` | Builds `src/configpanel/` into `public/`; shares React as a singleton with the admin. |
133
- | `test/plugin.test.js` | Plugin tests (`node:test`). |
134
- | `docs/screenshots/` | App Store screenshots, listed in `package.json` under `signalk.screenshots`. |
package/CLAUDE.md DELETED
@@ -1 +0,0 @@
1
- @AGENTS.md
package/eslint.config.js DELETED
@@ -1,59 +0,0 @@
1
- const prettier = require('eslint-config-prettier')
2
-
3
- module.exports = [
4
- { ignores: ['src/**', 'public/remoteEntry.js', 'public/540.js', 'public/805.js', 'public/main.js'] },
5
- {
6
- files: ['plugin/**/*.js', 'test/**/*.js'],
7
- languageOptions: {
8
- ecmaVersion: 2022,
9
- sourceType: 'commonjs',
10
- globals: {
11
- require: 'readonly',
12
- module: 'readonly',
13
- exports: 'readonly',
14
- __dirname: 'readonly',
15
- __filename: 'readonly',
16
- process: 'readonly',
17
- console: 'readonly',
18
- setTimeout: 'readonly',
19
- clearTimeout: 'readonly',
20
- setInterval: 'readonly',
21
- clearInterval: 'readonly',
22
- globalThis: 'readonly'
23
- }
24
- },
25
- rules: {
26
- 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
27
- 'no-undef': 'error'
28
- }
29
- },
30
- {
31
- files: ['public/dock.js'],
32
- languageOptions: {
33
- ecmaVersion: 2022,
34
- sourceType: 'script',
35
- globals: {
36
- window: 'readonly',
37
- document: 'readonly',
38
- navigator: 'readonly',
39
- fetch: 'readonly',
40
- console: 'readonly',
41
- setTimeout: 'readonly',
42
- clearTimeout: 'readonly',
43
- setInterval: 'readonly',
44
- requestAnimationFrame: 'readonly',
45
- Promise: 'readonly',
46
- Set: 'readonly',
47
- Infinity: 'readonly',
48
- MutationObserver: 'readonly',
49
- URLSearchParams: 'readonly',
50
- location: 'readonly'
51
- }
52
- },
53
- rules: {
54
- 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
55
- 'no-undef': 'error'
56
- }
57
- },
58
- prettier
59
- ]
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3
- "release-type": "node",
4
- "include-component-in-tag": false,
5
- "changelog-type": "github",
6
- "skip-changelog": true,
7
- "pull-request-title-pattern": "chore(release): ${version}",
8
- "packages": {
9
- ".": {}
10
- }
11
- }