@stacksjs/defaults 0.75.41 → 0.75.42

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 (98) hide show
  1. package/ai/skills/stacks-actions/SKILL.md +1 -1
  2. package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
  3. package/ai/skills/stacks-chat/SKILL.md +43 -1
  4. package/ai/skills/stacks-cloud/SKILL.md +36 -0
  5. package/ai/skills/stacks-dashboard/SKILL.md +16 -2
  6. package/ai/skills/stacks-database/SKILL.md +24 -3
  7. package/ai/skills/stacks-deploy/SKILL.md +7 -1
  8. package/ai/skills/stacks-desktop/SKILL.md +10 -0
  9. package/ai/skills/stacks-development/SKILL.md +1 -1
  10. package/ai/skills/stacks-migrations/SKILL.md +2 -2
  11. package/ai/skills/stacks-models/SKILL.md +38 -2
  12. package/ai/skills/stacks-orm/SKILL.md +2 -2
  13. package/ai/skills/stacks-security/SKILL.md +28 -1
  14. package/app/Actions/Auth/DataExportAction.test.ts +84 -0
  15. package/app/Actions/Auth/DataExportAction.ts +40 -0
  16. package/app/Actions/Dashboard/Content/FileReprocessAction.ts +1 -1
  17. package/app/Actions/Dashboard/Content/file-manager.ts +120 -8
  18. package/app/Actions/Dashboard/Content/file-metadata.ts +108 -12
  19. package/app/Actions/Dashboard/Content/file-pipeline.test.ts +13 -9
  20. package/app/Actions/Dashboard/Content/file-preview.test.ts +487 -0
  21. package/app/Actions/Dashboard/Content/file-preview.ts +548 -0
  22. package/app/Jobs/GenerateStoragePreviewJob.ts +47 -0
  23. package/app/Jobs/OptimizeStorageImageJob.ts +7 -3
  24. package/app/Jobs/PruneRetainedDataJob.ts +46 -0
  25. package/app/Models/Activity.ts +2 -0
  26. package/app/Models/CampaignSend.ts +2 -0
  27. package/app/Models/Card.ts +1 -0
  28. package/app/Models/CardComment.ts +1 -0
  29. package/app/Models/Comment.ts +5 -0
  30. package/app/Models/CommunicationSuppression.ts +2 -1
  31. package/app/Models/ConsentEvent.ts +4 -3
  32. package/app/Models/Content/Author.ts +5 -0
  33. package/app/Models/EmailListSubscriber.ts +1 -0
  34. package/app/Models/EmailSuppression.ts +2 -0
  35. package/app/Models/Forms/FormSubmission.ts +5 -0
  36. package/app/Models/GdprRequest.ts +77 -0
  37. package/app/Models/MagicLinkToken.ts +2 -0
  38. package/app/Models/Notification.ts +2 -0
  39. package/app/Models/NotificationDelivery.ts +4 -0
  40. package/app/Models/PaymentMethod.ts +5 -0
  41. package/app/Models/PaymentTransaction.ts +1 -0
  42. package/app/Models/PersonalAccessToken.ts +3 -0
  43. package/app/Models/Referral.ts +4 -1
  44. package/app/Models/ReferralCode.ts +4 -1
  45. package/app/Models/Request.ts +3 -0
  46. package/app/Models/SmsOptOut.ts +2 -0
  47. package/app/Models/SocialAccount.ts +3 -0
  48. package/app/Models/SocialPost.ts +2 -0
  49. package/app/Models/StorageItemTask.ts +14 -8
  50. package/app/Models/Subscriber.ts +2 -0
  51. package/app/Models/SubscriberEmail.ts +2 -0
  52. package/app/Models/Subscription.ts +1 -0
  53. package/app/Models/TeamInvitation.ts +2 -0
  54. package/app/Models/TeamMember.ts +1 -0
  55. package/app/Models/User.ts +5 -0
  56. package/app/Models/commerce/Bid.ts +3 -0
  57. package/app/Models/commerce/Cart.ts +2 -0
  58. package/app/Models/commerce/Courier.ts +7 -0
  59. package/app/Models/commerce/CourierPing.ts +3 -0
  60. package/app/Models/commerce/Customer.ts +5 -0
  61. package/app/Models/commerce/DeliveryStop.ts +7 -0
  62. package/app/Models/commerce/GiftCard.ts +4 -0
  63. package/app/Models/commerce/Order.ts +5 -0
  64. package/app/Models/commerce/OrderItem.ts +2 -0
  65. package/app/Models/commerce/Payment.ts +5 -0
  66. package/app/Models/commerce/Pledge.ts +3 -0
  67. package/app/Models/commerce/Transaction.ts +2 -0
  68. package/app/Models/commerce/WaitlistProduct.ts +5 -0
  69. package/app/Models/commerce/WaitlistRestaurant.ts +4 -0
  70. package/ide/vscode/.vscode/extensions.json +1 -1
  71. package/ide/vscode/.vscode/settings.json +8 -149
  72. package/ide/vscode/README.md +48 -23
  73. package/ide/vscode/build.ts +43 -0
  74. package/ide/vscode/package.json +305 -56
  75. package/ide/vscode/scripts/stx-contributes.ts +66 -0
  76. package/ide/vscode/src/env-file.ts +103 -0
  77. package/ide/vscode/src/env.ts +241 -0
  78. package/ide/vscode/src/extension.ts +120 -26
  79. package/ide/vscode/src/pickier-protocol.ts +51 -0
  80. package/ide/vscode/src/pickier-worker.ts +92 -0
  81. package/ide/vscode/src/pickier.ts +433 -0
  82. package/ide/vscode/src/project.ts +14 -4
  83. package/ide/vscode/src/stacks.ts +18 -11
  84. package/ide/vscode/tests/build.test.ts +58 -0
  85. package/ide/vscode/tests/env.test.ts +166 -0
  86. package/ide/vscode/tests/extension.test.ts +8 -0
  87. package/ide/vscode/tests/fake-vscode.ts +228 -0
  88. package/ide/vscode/tests/manifest.test.ts +88 -0
  89. package/ide/vscode/tests/pickier.test.ts +202 -0
  90. package/ide/vscode/tsconfig.json +2 -2
  91. package/package.json +2 -2
  92. package/resources/components/Dashboard/Content/FileManagerDashboard.stx +2 -0
  93. package/resources/components/Dashboard/FileViewer/MediaCard.stx +14 -3
  94. package/routes/auth.ts +4 -0
  95. package/vcs/github/workflows/buddy-bot.yml +2 -2
  96. package/vcs/github/workflows/ci.yml +3 -3
  97. package/vcs/github/workflows/release.yml +1 -1
  98. package/ide/vscode/src/vscode.d.ts +0 -181
@@ -1,8 +1,31 @@
1
1
  # Stacks for VS Code
2
2
 
3
- Build a Stacks app without leaving the editor. Start the dev server, preview it in VS Code's built-in Simple Browser, and run any `buddy` command from the Command Palette. The extension also installs a small pack of extensions that Stacks projects are configured for.
3
+ Everything a Stacks project needs in the editor, in one extension: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every `buddy` command. It installs no other extensions and works without any.
4
4
 
5
- The extension activates in workspaces that contain a `buddy` file or a `config/app.ts`.
5
+ The Stacks commands, pickier and the env features activate in workspaces that contain a `buddy` file or a `config/app.ts`. stx support also starts for any `.stx` file.
6
+
7
+ ## stx templates
8
+
9
+ `.stx` files get the full stx language support: highlighting, completions for directives, components and props, hovers, diagnostics, go to definition, folding, semantic highlighting, snippets, and previews of utility classes with their colors.
10
+
11
+ It is the same code as the standalone [stx extension](https://marketplace.visualstudio.com/items?itemName=Stacks.vscode-stx) (`Stacks.vscode-stx`), built in from `@stacksjs/stx-vscode`. You do not need that extension; if you have both, it stands down so nothing is registered twice.
12
+
13
+ ## Pickier
14
+
15
+ Files `./buddy lint` checks (`.ts`, `.js`, `.json`, `.md`, `.yaml`) are linted as you type, with the project's own pickier and its config (`config/code-style.ts`, `pickier.config.ts` or `.config/pickier.ts`), so the editor and `./buddy lint` always agree. Pickier runs in a Bun process per project, on the project's `pantry/.bin/bun` when it has one.
16
+
17
+ - **Format Document** formats with pickier when the extension is the formatter: `"editor.defaultFormatter": "Stacks.vscode-stacks"`, which new projects already set.
18
+ - **Fix all**: the `source.fixAll.pickier` code action applies every fix `./buddy lint --fix` would. New projects run it on save through `"editor.codeActionsOnSave": { "source.fixAll.pickier": "explicit" }`. It needs pickier 0.1.66 or later.
19
+ - **Quick fixes** on a pickier problem: fix all, or `// pickier-disable-next-line <rule>` for that line.
20
+
21
+ ## Env files
22
+
23
+ - **Hover** an `encrypted:` value to see it decrypted, with the same code and keys `./buddy env:get` uses: `DOTENV_PRIVATE_KEY_<ENV>` or `DOTENV_PRIVATE_KEY`, from `.env.keys` or the environment. The value is only shown; it is never cached, logged or written anywhere.
24
+ - **Missing keys**: keys `.env.example` declares that `.env` does not set are flagged in `.env`.
25
+ - **Commands** run the project's `./buddy env:*` directly, without a shell, so a value you set does not end up in your shell history. They act on the env file that is open, or `.env`.
26
+ - The **preview** decrypts an encrypted `APP_URL` or `PORT` the same way, so it opens the URL `./buddy dev` serves.
27
+
28
+ VS Code highlights `.env` files itself.
6
29
 
7
30
  ## Commands
8
31
 
@@ -13,6 +36,13 @@ Open the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) and type `Stacks`.
13
36
  | **Stacks: Open Preview** | Opens the running dev server in the Simple Browser, beside your editor. If nothing is running, it offers to start the dev server. |
14
37
  | **Stacks: Start Dev Server** | Runs `./buddy dev` in a terminal named `Stacks Dev` at the project root. Once the server is up, the preview opens in the Simple Browser. |
15
38
  | **Stacks: Run Buddy Command...** | Lists every command `./buddy list` knows, including your own in `app/Commands/`. Pick one, and if it takes arguments you are asked for them. You can also type a full command line, such as `migrate --diff` or `make:model Post`. The command runs in a terminal named `Stacks Buddy`. |
39
+ | **Stacks: Fix All Lint Problems** | Applies pickier's fixes to the open file. |
40
+ | **Stacks: Restart Pickier** | Restarts the pickier process, after changing its config outside the editor or updating pickier. Saving the config in the editor restarts it for you. |
41
+ | **Stacks: Env: Get Value...** | `./buddy env:get`: pick a key, then copy its value. |
42
+ | **Stacks: Env: Set Value...** | `./buddy env:set`: the value is typed into a password box, and encrypted when the file is. |
43
+ | **Stacks: Env: Encrypt File** | `./buddy env:encrypt`. |
44
+ | **Stacks: Env: Decrypt File** | `./buddy env:decrypt`, after a warning: it writes every value to disk in plaintext. |
45
+ | **Stacks: Env: Rotate Keys** | `./buddy env:rotate`, after a warning: deployments holding the old private key can no longer decrypt the file. |
16
46
 
17
47
  The **Stacks** item in the status bar opens the preview.
18
48
 
@@ -39,43 +69,38 @@ The extension checks that the frontend port is accepting connections before it o
39
69
  | `stacks.devServer.args` | `[]` | Extra arguments for `./buddy dev`, e.g. `["frontend"]` or `["--site"]`. |
40
70
  | `stacks.devServer.openPreview` | `true` | Open the Simple Browser once the dev server is up, instead of letting `buddy dev` open your system browser. |
41
71
  | `stacks.statusBar.enabled` | `true` | Show the Stacks status bar item. |
72
+ | `stacks.pickier.enable` | `true` | Lint, format and fix with the project's pickier. |
73
+ | `stacks.pickier.run` | `"onType"` | Lint as you type (`onType`) or only on save (`onSave`). |
74
+ | `stacks.bunPath` | `""` | The Bun that runs pickier. Empty means the project's `pantry/.bin/bun`, then `bun` on the `PATH`. |
75
+ | `stacks.env.decryptOnHover` | `true` | Show encrypted env values decrypted on hover. |
76
+ | `stacks.env.missingKeys` | `true` | Flag keys `.env.example` has that `.env` does not set. |
42
77
 
43
- The extension also sets a few editor defaults for Stacks projects: `.stx` files use HTML language support, the `buddy` script is highlighted as a shell script, `npm.packageManager` is `bun`, Go to Definition prefers source files over `.d.ts`, and TypeScript uses the workspace version.
78
+ The `stx.*` settings (diagnostics, completion, hover, utility classes and so on) are the stx extension's, and work the same here.
44
79
 
45
- ## Included extensions
80
+ The extension also sets a few editor defaults for Stacks projects: the `buddy` script is highlighted as a shell script, `npm.packageManager` is `bun`, Go to Definition prefers source files over `.d.ts`, and TypeScript uses the workspace version.
46
81
 
47
- - [Bun for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=oven.bun-vscode) - Bun runtime and test integration
48
- - [Dotenvx](https://marketplace.visualstudio.com/items?itemName=dotenv.dotenvx-vscode) - encrypted environment file support
49
- - [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - editor integration for the project's lint rules
50
- - [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) - Markdown linting
51
- - [shell-format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format) - shell script and Dockerfile formatting
52
- - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) - spell checking with the Stacks dictionary
53
- - [Total TypeScript Error Translator](https://marketplace.visualstudio.com/items?itemName=mattpocock.ts-error-translator) - plain-English TypeScript errors
54
- - [Prettify TypeScript](https://marketplace.visualstudio.com/items?itemName=mylesmurphy.prettify-ts) - readable type hovers
55
- - [Twoslash Query Comments](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-twoslash-queries) - inline `// ^?` type queries
56
- - [AWS Toolkit](https://marketplace.visualstudio.com/items?itemName=amazonwebservices.aws-toolkit-vscode) - the AWS resources `buddy deploy` creates
82
+ ## No extension pack
57
83
 
58
- Some extensions were dropped from the pack because VS Code now does the same thing itself:
84
+ Earlier versions installed a pack of other extensions. It is gone, and the extension depends on none:
59
85
 
60
- - **Goto Definition Alias**: built-in **Go to Source Definition**, which this extension enables by default.
61
- - **npm Intellisense**: TypeScript's built-in package import completions.
62
- - **DotENV**: VS Code's built-in `dotenv` language highlights `.env` and `.env.*` files.
63
- - **Gremlins**: built-in Unicode highlighting (`editor.unicodeHighlight.*`) flags invisible and confusable characters.
86
+ - **stx Language Support**, **ESLint** and **Dotenvx** are replaced by the built-in stx, pickier and env support above. Stacks lints with pickier, not ESLint.
87
+ - **Bun for Visual Studio Code**, **AWS Toolkit**, **markdownlint**, **shell-format**, **Code Spell Checker**, **Total TypeScript Error Translator**, **Prettify TypeScript** and **Twoslash Query Comments** were dropped. They are general-purpose tools rather than anything Stacks-specific, and markdownlint and shell-format formatted files pickier formats. Install any of them yourself if you want them.
64
88
 
65
89
  ## Development
66
90
 
67
91
  ```bash
68
- bun run build # bundle src/ into dist/extension.js
69
- bun test ./tests # unit tests for URL detection, `buddy list` parsing and the commands
92
+ bun run build # bundle src/ into dist/ (extension, pickier worker, stx assets)
93
+ bun test ./tests # unit tests, plus a build that must load as CommonJS on Node
70
94
  bun run typecheck
95
+ bun run sync:stx # after updating @stacksjs/stx-vscode: copy its contributions into package.json
71
96
  bun run package # build and create a .vsix
72
97
  code --install-extension vscode-stacks-<version>.vsix
73
98
  ```
74
99
 
75
- The extension has no runtime dependencies. It is published automatically by the Stacks release workflow, and `vscode:prepublish` builds `dist/` first.
100
+ The extension has no runtime dependencies: `@stacksjs/stx-vscode` and the env decryption from `core/env` are bundled into `dist/extension.js`. It is published automatically by the Stacks release workflow, and `vscode:prepublish` builds `dist/` first.
76
101
 
77
102
  ## Relevant links
78
103
 
79
104
  - [GitHub](https://github.com/stacksjs/stacks)
80
- - [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=stacks.vscode-stacks)
105
+ - [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=Stacks.vscode-stacks)
81
106
  - [IDE setup guide](https://stacksjs.com/docs/bootcamp/how-to/ide-setup)
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Builds the extension into dist/:
3
+ *
4
+ * extension.js the extension, for VS Code's Node host; only `vscode` is external
5
+ * pickier-worker.js the Bun process that runs the project's pickier (src/pickier-worker.ts)
6
+ * pickier-worker.bunfig.toml an empty bunfig, so the worker skips the project's preloads
7
+ * stx/ grammar, language configuration and snippets from @stacksjs/stx-vscode
8
+ *
9
+ * `vsce package` runs this first (`vscode:prepublish`), and `files` in
10
+ * package.json ships exactly these.
11
+ */
12
+ import { cpSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
13
+ import { dirname, join } from 'node:path'
14
+ import process from 'node:process'
15
+
16
+ const here = import.meta.dir
17
+ const dist = join(here, 'dist')
18
+
19
+ rmSync(dist, { recursive: true, force: true })
20
+ mkdirSync(dist, { recursive: true })
21
+
22
+ const builds = await Promise.all([
23
+ // bunfig stays out: the stx utility-class engine imports it only to load a
24
+ // config file, which the extension never asks for, and its module-scope
25
+ // `await` and `import.meta.require` would make the CommonJS bundle a syntax
26
+ // error in VS Code's Node host. tests/build.test.ts parses the bundle.
27
+ Bun.build({ entrypoints: [join(here, 'src/extension.ts')], outdir: dist, target: 'node', format: 'cjs', external: ['vscode', 'bunfig'], minify: true }),
28
+ Bun.build({ entrypoints: [join(here, 'src/pickier-worker.ts')], outdir: dist, target: 'bun', format: 'esm' }),
29
+ ])
30
+
31
+ for (const build of builds) {
32
+ if (!build.success) {
33
+ console.error(build.logs)
34
+ process.exit(1)
35
+ }
36
+ }
37
+
38
+ writeFileSync(join(dist, 'pickier-worker.bunfig.toml'), '# Intentionally empty: the pickier worker must not run the project\'s bunfig preloads.\n')
39
+
40
+ const stxAssets = join(dirname(Bun.resolveSync('@stacksjs/stx-vscode/contributes.json', here)), 'assets')
41
+ cpSync(stxAssets, join(dist, 'stx'), { recursive: true })
42
+
43
+ console.log('Built dist/')
@@ -2,8 +2,8 @@
2
2
  "publisher": "Stacks",
3
3
  "name": "vscode-stacks",
4
4
  "displayName": "Stacks",
5
- "version": "0.75.41",
6
- "description": "Develop Stacks apps without leaving VS Code: preview the dev server in the Simple Browser, start it, and run any buddy command.",
5
+ "version": "0.75.42",
6
+ "description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
7
7
  "license": "MIT",
8
8
  "funding": "https://github.com/sponsors/chrisbbreuer",
9
9
  "sponsor": {
@@ -21,23 +21,29 @@
21
21
  "keywords": [
22
22
  "stacks",
23
23
  "stacksjs",
24
+ "stx",
25
+ "pickier",
26
+ "lint",
27
+ "format",
28
+ "dotenv",
29
+ "env",
24
30
  "buddy",
25
31
  "preview",
26
- "simple browser",
27
- "dev server",
28
- "extension pack"
32
+ "dev server"
29
33
  ],
30
34
  "categories": [
31
- "Extension Packs",
35
+ "Programming Languages",
36
+ "Linters",
37
+ "Formatters",
32
38
  "Other"
33
39
  ],
34
40
  "icon": "logo.png",
35
41
  "main": "./dist/extension.js",
36
42
  "files": [
37
- ".vscode/extensions.json",
38
- ".vscode/settings.json",
39
- ".vscode/stacks.code-snippets",
40
43
  "dist/extension.js",
44
+ "dist/pickier-worker.js",
45
+ "dist/pickier-worker.bunfig.toml",
46
+ "dist/stx/**",
41
47
  "LICENSE.md",
42
48
  "README.md",
43
49
  "logo.png"
@@ -50,7 +56,8 @@
50
56
  ],
51
57
  "activationEvents": [
52
58
  "workspaceContains:buddy",
53
- "workspaceContains:config/app.ts"
59
+ "workspaceContains:config/app.ts",
60
+ "onLanguage:stx"
54
61
  ],
55
62
  "capabilities": {
56
63
  "untrustedWorkspaces": {
@@ -60,10 +67,11 @@
60
67
  "virtualWorkspaces": false
61
68
  },
62
69
  "scripts": {
63
- "build": "bun build ./src/extension.ts --outdir dist --target node --format cjs --external vscode",
70
+ "build": "bun build.ts",
64
71
  "vscode:prepublish": "bun run build",
65
72
  "test": "bun test ./tests",
66
73
  "typecheck": "bun x --bun tsc --noEmit -p tsconfig.json",
74
+ "sync:stx": "bun scripts/stx-contributes.ts --write",
67
75
  "package": "bunx --bun vsce package --no-dependencies",
68
76
  "release": "bunx --bun vsce publish --no-dependencies"
69
77
  },
@@ -90,6 +98,50 @@
90
98
  "title": "Run Buddy Command...",
91
99
  "category": "Stacks",
92
100
  "icon": "$(terminal)"
101
+ },
102
+ {
103
+ "command": "stacks.pickier.fixAll",
104
+ "title": "Fix All Lint Problems",
105
+ "category": "Stacks"
106
+ },
107
+ {
108
+ "command": "stacks.pickier.restart",
109
+ "title": "Restart Pickier",
110
+ "category": "Stacks"
111
+ },
112
+ {
113
+ "command": "stacks.env.get",
114
+ "title": "Env: Get Value...",
115
+ "category": "Stacks"
116
+ },
117
+ {
118
+ "command": "stacks.env.set",
119
+ "title": "Env: Set Value...",
120
+ "category": "Stacks"
121
+ },
122
+ {
123
+ "command": "stacks.env.encrypt",
124
+ "title": "Env: Encrypt File",
125
+ "category": "Stacks"
126
+ },
127
+ {
128
+ "command": "stacks.env.decrypt",
129
+ "title": "Env: Decrypt File",
130
+ "category": "Stacks"
131
+ },
132
+ {
133
+ "command": "stacks.env.rotate",
134
+ "title": "Env: Rotate Keys",
135
+ "category": "Stacks"
136
+ },
137
+ {
138
+ "command": "stx.sortClasses",
139
+ "title": "Sort Utility Classes",
140
+ "category": "stx"
141
+ },
142
+ {
143
+ "command": "css.reload",
144
+ "title": "Css: Reload Configuration"
93
145
  }
94
146
  ],
95
147
  "menus": {
@@ -105,65 +157,262 @@
105
157
  {
106
158
  "command": "stacks.runBuddyCommand",
107
159
  "when": "stacks.isProject"
108
- }
109
- ]
110
- },
111
- "configuration": {
112
- "title": "Stacks",
113
- "properties": {
114
- "stacks.preview.url": {
115
- "type": "string",
116
- "default": "",
117
- "markdownDescription": "URL `Stacks: Open Preview` always opens, e.g. `http://localhost:3000/dashboard`. Leave empty to find the running dev server the way `./buddy dev` picks its URL (`APP_URL`, `PORT`, `APP_PATH`)."
118
160
  },
119
- "stacks.preview.preferLocalhost": {
120
- "type": "boolean",
121
- "default": false,
122
- "markdownDescription": "Preview `http://localhost:<PORT>` even when `APP_URL` gives the app a pretty `https://` domain. Useful when the local certificate is not trusted, which leaves the Simple Browser blank."
161
+ {
162
+ "command": "stacks.pickier.fixAll",
163
+ "when": "stacks.isProject"
123
164
  },
124
- "stacks.devServer.args": {
125
- "type": "array",
126
- "items": {
127
- "type": "string"
128
- },
129
- "default": [],
130
- "markdownDescription": "Extra arguments for `./buddy dev`, e.g. `[\"frontend\"]` or `[\"--site\"]`. They are passed to the shell as written."
165
+ {
166
+ "command": "stacks.pickier.restart",
167
+ "when": "stacks.isProject"
131
168
  },
132
- "stacks.devServer.openPreview": {
133
- "type": "boolean",
134
- "default": true,
135
- "markdownDescription": "Open the preview in the Simple Browser once `Stacks: Start Dev Server` is up, instead of letting `./buddy dev` open the system browser."
169
+ {
170
+ "command": "stacks.env.get",
171
+ "when": "stacks.isProject"
136
172
  },
137
- "stacks.statusBar.enabled": {
138
- "type": "boolean",
139
- "default": true,
140
- "description": "Show the Stacks item in the status bar, which opens the preview."
173
+ {
174
+ "command": "stacks.env.set",
175
+ "when": "stacks.isProject"
176
+ },
177
+ {
178
+ "command": "stacks.env.encrypt",
179
+ "when": "stacks.isProject"
180
+ },
181
+ {
182
+ "command": "stacks.env.decrypt",
183
+ "when": "stacks.isProject"
184
+ },
185
+ {
186
+ "command": "stacks.env.rotate",
187
+ "when": "stacks.isProject"
141
188
  }
142
- }
189
+ ]
143
190
  },
191
+ "configuration": [
192
+ {
193
+ "title": "Stacks",
194
+ "properties": {
195
+ "stacks.preview.url": {
196
+ "type": "string",
197
+ "default": "",
198
+ "markdownDescription": "URL `Stacks: Open Preview` always opens, e.g. `http://localhost:3000/dashboard`. Leave empty to find the running dev server the way `./buddy dev` picks its URL (`APP_URL`, `PORT`, `APP_PATH`)."
199
+ },
200
+ "stacks.preview.preferLocalhost": {
201
+ "type": "boolean",
202
+ "default": false,
203
+ "markdownDescription": "Preview `http://localhost:<PORT>` even when `APP_URL` gives the app a pretty `https://` domain. Useful when the local certificate is not trusted, which leaves the Simple Browser blank."
204
+ },
205
+ "stacks.devServer.args": {
206
+ "type": "array",
207
+ "items": {
208
+ "type": "string"
209
+ },
210
+ "default": [],
211
+ "markdownDescription": "Extra arguments for `./buddy dev`, e.g. `[\"frontend\"]` or `[\"--site\"]`. They are passed to the shell as written."
212
+ },
213
+ "stacks.devServer.openPreview": {
214
+ "type": "boolean",
215
+ "default": true,
216
+ "markdownDescription": "Open the preview in the Simple Browser once `Stacks: Start Dev Server` is up, instead of letting `./buddy dev` open the system browser."
217
+ },
218
+ "stacks.statusBar.enabled": {
219
+ "type": "boolean",
220
+ "default": true,
221
+ "description": "Show the Stacks item in the status bar, which opens the preview."
222
+ },
223
+ "stacks.pickier.enable": {
224
+ "type": "boolean",
225
+ "default": true,
226
+ "markdownDescription": "Lint with the project's own pickier and config, the same as `./buddy lint`, and offer it as a formatter and a `source.fixAll.pickier` code action."
227
+ },
228
+ "stacks.pickier.run": {
229
+ "type": "string",
230
+ "enum": [
231
+ "onType",
232
+ "onSave"
233
+ ],
234
+ "default": "onType",
235
+ "markdownDescription": "Lint as you type, or only when a file is saved."
236
+ },
237
+ "stacks.bunPath": {
238
+ "type": "string",
239
+ "default": "",
240
+ "markdownDescription": "The Bun binary that runs pickier. Leave empty to use the project's `pantry/.bin/bun`, then `bun` on the `PATH`."
241
+ },
242
+ "stacks.env.decryptOnHover": {
243
+ "type": "boolean",
244
+ "default": true,
245
+ "markdownDescription": "Hovering an `encrypted:` value in an env file shows it decrypted, with the private key from `.env.keys` or `DOTENV_PRIVATE_KEY*`. The plaintext is only shown, never written anywhere."
246
+ },
247
+ "stacks.env.missingKeys": {
248
+ "type": "boolean",
249
+ "default": true,
250
+ "markdownDescription": "Flag keys `.env.example` declares that `.env` does not set."
251
+ }
252
+ }
253
+ },
254
+ {
255
+ "title": "stx",
256
+ "properties": {
257
+ "stxTypescriptPlugin.enabled": {
258
+ "type": "boolean",
259
+ "default": true,
260
+ "description": "Enable TypeScript language features in stx files"
261
+ },
262
+ "stx.diagnostics.enable": {
263
+ "type": "boolean",
264
+ "default": true,
265
+ "description": "Enable diagnostics (errors and warnings) for stx files"
266
+ },
267
+ "stx.diagnostics.validateUnclosedDirectives": {
268
+ "type": "boolean",
269
+ "default": true,
270
+ "description": "Validate unclosed directives like @if without @endif"
271
+ },
272
+ "stx.diagnostics.validateMismatchedDirectives": {
273
+ "type": "boolean",
274
+ "default": true,
275
+ "description": "Validate mismatched directives like @if closed with @endforeach"
276
+ },
277
+ "stx.diagnostics.validateTemplatePaths": {
278
+ "type": "boolean",
279
+ "default": true,
280
+ "description": "Validate that template paths in @include and @component directives exist"
281
+ },
282
+ "stx.completion.enable": {
283
+ "type": "boolean",
284
+ "default": true,
285
+ "description": "Enable auto-completion for stx directives"
286
+ },
287
+ "stx.completion.showSnippets": {
288
+ "type": "boolean",
289
+ "default": true,
290
+ "description": "Show snippet completions with placeholders for directive parameters"
291
+ },
292
+ "stx.hover.enable": {
293
+ "type": "boolean",
294
+ "default": true,
295
+ "description": "Enable hover documentation for stx directives"
296
+ },
297
+ "stx.hover.showExamples": {
298
+ "type": "boolean",
299
+ "default": true,
300
+ "description": "Show code examples in hover documentation"
301
+ },
302
+ "stx.codeActions.enable": {
303
+ "type": "boolean",
304
+ "default": true,
305
+ "description": "Enable quick fixes and code actions"
306
+ },
307
+ "stx.folding.enable": {
308
+ "type": "boolean",
309
+ "default": true,
310
+ "description": "Enable code folding for directive blocks"
311
+ },
312
+ "stx.semanticHighlighting.enable": {
313
+ "type": "boolean",
314
+ "default": true,
315
+ "description": "Enable semantic syntax highlighting for directives"
316
+ },
317
+ "stx.utilityClasses.enable": {
318
+ "type": "boolean",
319
+ "default": true,
320
+ "description": "Enable utility class features (tooltips, color previews, sorting)"
321
+ },
322
+ "stx.utilityClasses.framework": {
323
+ "type": "string",
324
+ "enum": [
325
+ "tailwind",
326
+ "unocss",
327
+ "auto"
328
+ ],
329
+ "default": "auto",
330
+ "markdownDescription": "Utility CSS framework to use. `auto` will detect from config files"
331
+ },
332
+ "stx.utilityClasses.colorPreview": {
333
+ "type": "boolean",
334
+ "default": true,
335
+ "description": "Show inline color decorations for color utility classes"
336
+ },
337
+ "stx.utilityClasses.hoverPreview": {
338
+ "type": "boolean",
339
+ "default": true,
340
+ "description": "Show CSS output when hovering over utility classes"
341
+ },
342
+ "stx.utilityClasses.underline": {
343
+ "type": "boolean",
344
+ "default": true,
345
+ "description": "Underline matched utility classes"
346
+ },
347
+ "stx.utilityClasses.sortOnSave": {
348
+ "type": "boolean",
349
+ "default": false,
350
+ "description": "Automatically sort utility classes on file save"
351
+ },
352
+ "stx.utilityClasses.colorPreviewRadius": {
353
+ "type": "string",
354
+ "default": "0",
355
+ "description": "Border radius for color preview blocks ('0' for square like Tailwind, '50%' for circle)"
356
+ },
357
+ "stx.utilityClasses.selectionStyle": {
358
+ "type": "boolean",
359
+ "default": false,
360
+ "description": "Show CSS preview for selected utility classes"
361
+ },
362
+ "stx.utilityClasses.autocomplete": {
363
+ "type": "boolean",
364
+ "default": true,
365
+ "description": "Enable autocomplete for utility classes"
366
+ },
367
+ "css.remToPxRatio": {
368
+ "type": "number",
369
+ "default": 16,
370
+ "description": "Rem to px conversion ratio for hover previews"
371
+ }
372
+ }
373
+ }
374
+ ],
144
375
  "configurationDefaults": {
145
376
  "files.associations": {
146
- "buddy": "shellscript",
147
- "*.stx": "html"
377
+ "buddy": "shellscript"
148
378
  },
149
379
  "npm.packageManager": "bun",
150
380
  "typescript.preferGoToSourceDefinition": true,
151
381
  "typescript.tsdk": "node_modules/typescript/lib"
152
- }
382
+ },
383
+ "languages": [
384
+ {
385
+ "id": "stx",
386
+ "aliases": [
387
+ "stx",
388
+ "STX"
389
+ ],
390
+ "extensions": [
391
+ ".stx"
392
+ ],
393
+ "configuration": "./dist/stx/languages/stx.configuration.json"
394
+ }
395
+ ],
396
+ "grammars": [
397
+ {
398
+ "language": "stx",
399
+ "scopeName": "text.html.ts.stx",
400
+ "path": "./dist/stx/syntaxes/stx.tmLanguage.json",
401
+ "embeddedLanguages": {
402
+ "source.css": "css",
403
+ "source.js": "javascript",
404
+ "source.ts": "typescript",
405
+ "meta.embedded.block.typescript": "typescript",
406
+ "meta.embedded.block.javascript": "javascript",
407
+ "meta.embedded.line.typescript": "typescript",
408
+ "meta.component.parameters.stx": "typescript"
409
+ }
410
+ }
411
+ ]
153
412
  },
154
- "extensionPack": [
155
- "dotenv.dotenvx-vscode",
156
- "amazonwebservices.aws-toolkit-vscode",
157
- "dbaeumer.vscode-eslint",
158
- "davidanson.vscode-markdownlint",
159
- "foxundermoon.shell-format",
160
- "mattpocock.ts-error-translator",
161
- "mylesmurphy.prettify-ts",
162
- "Orta.vscode-twoslash-queries",
163
- "oven.bun-vscode",
164
- "streetsidesoftware.code-spell-checker"
165
- ],
166
413
  "devDependencies": {
414
+ "@stacksjs/stx-vscode": "^0.2.352",
415
+ "@types/vscode": "~1.109.0",
167
416
  "@vscode/vsce": "^4.0.0"
168
417
  }
169
418
  }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Keeps the stx half of package.json's `contributes` equal to what
3
+ * `@stacksjs/stx-vscode` ships.
4
+ *
5
+ * VS Code reads languages, grammars, commands and settings only from the
6
+ * manifest, so the built-in stx support needs them declared here, pointing at
7
+ * dist/stx/ (copied there by build.ts). The library describes them in
8
+ * `contributes.json`; this derives the manifest from it rather than keeping a
9
+ * second copy by hand. Snippets are left out on purpose: the extension offers
10
+ * them as completions only when the stx extension is not installed, because
11
+ * a manifest entry would show every snippet twice next to it.
12
+ *
13
+ * bun scripts/stx-contributes.ts --write update package.json (`bun run sync:stx`)
14
+ *
15
+ * tests/manifest.test.ts fails while the two disagree.
16
+ */
17
+ import { readFileSync, writeFileSync } from 'node:fs'
18
+ import { join } from 'node:path'
19
+ import process from 'node:process'
20
+
21
+ export interface StxContributes {
22
+ languages: Array<Record<string, unknown> & { id: string, configuration: string }>
23
+ grammars: Array<Record<string, unknown> & { language: string, path: string }>
24
+ commands: Array<{ command: string, title: string, category?: string }>
25
+ configuration: { title: string, properties: Record<string, unknown> }
26
+ }
27
+
28
+ const STX_DIR = './dist/stx/'
29
+
30
+ function fromStx(path: string): string {
31
+ return STX_DIR + path.replace(/^\.\//, '')
32
+ }
33
+
34
+ /** `manifest` with its stx contributions replaced by the library's. */
35
+ export function withStxContributes(manifest: any, stx: StxContributes): any {
36
+ const stxCommands = new Set(stx.commands.map(command => command.command))
37
+ const contributes = manifest.contributes
38
+ const sections: Array<{ title: string }> = Array.isArray(contributes.configuration) ? contributes.configuration : [contributes.configuration]
39
+
40
+ return {
41
+ ...manifest,
42
+ contributes: {
43
+ ...contributes,
44
+ languages: stx.languages.map(language => ({ ...language, configuration: fromStx(language.configuration) })),
45
+ grammars: stx.grammars.map(grammar => ({ ...grammar, path: fromStx(grammar.path) })),
46
+ commands: [...contributes.commands.filter((command: { command: string }) => !stxCommands.has(command.command)), ...stx.commands],
47
+ configuration: [...sections.filter(section => section.title !== stx.configuration.title), stx.configuration],
48
+ },
49
+ }
50
+ }
51
+
52
+ export function libraryContributes(root: string): StxContributes {
53
+ return JSON.parse(readFileSync(Bun.resolveSync('@stacksjs/stx-vscode/contributes.json', root), 'utf8'))
54
+ }
55
+
56
+ if (import.meta.main) {
57
+ const root = join(import.meta.dir, '..')
58
+ const path = join(root, 'package.json')
59
+ const manifest = JSON.parse(readFileSync(path, 'utf8'))
60
+ const next = `${JSON.stringify(withStxContributes(manifest, libraryContributes(root)), null, 2)}\n`
61
+
62
+ if (process.argv.includes('--write'))
63
+ writeFileSync(path, next)
64
+ else
65
+ process.stdout.write(next)
66
+ }