@programinglive/dev-workflow-mcp-server 1.3.5 → 1.3.6

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [1.3.6](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.3.5...v1.3.6) (2025-11-22)
6
+
7
+
8
+ ### ✨ Features
9
+
10
+ * **web:** replace Tailwind CDN with build process ([1e6e91f](https://github.com/programinglive/dev-workflow-mcp-server/commit/1e6e91f880d0445e39211d0d42aff1ca2e3e9253))
11
+
5
12
  ### [1.3.5](https://github.com/programinglive/dev-workflow-mcp-server/compare/v1.3.4...v1.3.5) (2025-11-22)
6
13
 
7
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@programinglive/dev-workflow-mcp-server",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "MCP server to enforce development workflow discipline",
5
5
  "homepage": "https://devworkflow.programinglive.com/",
6
6
  "type": "module",
@@ -10,7 +10,9 @@
10
10
  },
11
11
  "scripts": {
12
12
  "build": "vite build",
13
- "postbuild": "node scripts/build-docs.js",
13
+ "build:web": "node node_modules/@tailwindcss/cli/dist/index.mjs -i ./web/input.css -o ./web/output.css --minify",
14
+ "watch:web": "node node_modules/@tailwindcss/cli/dist/index.mjs -i ./web/input.css -o ./web/output.css --watch",
15
+ "postbuild": "npm run build:web && node scripts/build-docs.js",
14
16
  "dev": "node --watch index.js",
15
17
  "start": "node index.js",
16
18
  "local": "node index.js",
@@ -51,8 +53,12 @@
51
53
  "@commitlint/cli": "^20.1.0",
52
54
  "@commitlint/config-conventional": "^20.0.0",
53
55
  "@programinglive/commiter": "^1.1.8",
56
+ "@tailwindcss/cli": "^4.1.17",
57
+ "autoprefixer": "^10.4.22",
54
58
  "husky": "^9.1.7",
55
- "standard-version": "^9.5.0"
59
+ "postcss": "^8.5.6",
60
+ "standard-version": "^9.5.0",
61
+ "tailwindcss": "^4.1.17"
56
62
  },
57
63
  "standard-version": {
58
64
  "releaseCommitMessageFormat": "chore(release): {{currentTag}} 🚀",
@@ -0,0 +1,10 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: [
4
+ "./web/**/*.{html,js}",
5
+ ],
6
+ theme: {
7
+ extend: {},
8
+ },
9
+ plugins: [],
10
+ }
@@ -11,16 +11,17 @@ test('build generates dist/index.mjs file', async () => {
11
11
  const { stderr } = await exec('npm run build');
12
12
  // Allow the known vite warning about node:process
13
13
  const knownWarning = '[plugin vite:resolve] Module "node:process" has been externalized for browser compatibility';
14
+ const tailwindOutput = '≈ tailwindcss';
14
15
  const actualStderr = stderr.replace(/\x1B\[[0-9;]*m/g, ''); // Remove ANSI codes
15
16
  assert(
16
- actualStderr === '' || actualStderr.includes(knownWarning),
17
+ actualStderr === '' || actualStderr.includes(knownWarning) || actualStderr.includes(tailwindOutput),
17
18
  `Build should not have unexpected errors: ${actualStderr}`
18
19
  );
19
-
20
+
20
21
  // Verify the file exists
21
22
  const distPath = path.join(process.cwd(), 'dist', 'index.mjs');
22
23
  await access(distPath);
23
-
24
+
24
25
  // Verify it contains expected content
25
26
  const content = await readFile(distPath, 'utf-8');
26
27
  assert(content.includes('main'), 'Bundle should contain main function');
@@ -40,7 +41,7 @@ test('build script exists in package.json', async () => {
40
41
  const packagePath = path.join(process.cwd(), 'package.json');
41
42
  const content = await readFile(packagePath, 'utf-8');
42
43
  const pkg = JSON.parse(content);
43
-
44
+
44
45
  assert.strictEqual(typeof pkg.scripts.build, 'string');
45
46
  assert(pkg.scripts.build.includes('vite build'));
46
47
  });
package/web/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta charset="UTF-8">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
7
  <title>Dev Workflow Dashboard</title>
8
- <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="/output.css">
9
9
  <script src="https://unpkg.com/lucide@latest"></script>
10
10
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
11
11
  </head>
package/web/input.css ADDED
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
package/web/output.css ADDED
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.fixed\!{position:fixed!important}.relative{position:relative}.sticky{position:sticky}.top-1\/2{top:50%}.isolate{isolation:isolate}.z-50{z-index:50}.mx-auto{margin-inline:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-none{max-width:none}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.text-left{text-align:left}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.opacity-90{opacity:.9}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.select-none{-webkit-user-select:none;user-select:none}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
package/web/server.js CHANGED
@@ -82,7 +82,11 @@ async function start() {
82
82
  const url = new URL(req.url, `http://${req.headers.host}`);
83
83
  const userId = url.searchParams.get("user") || "default";
84
84
 
85
- if (req.method === "GET" && url.pathname === "/") {
85
+ if (req.method === "GET" && url.pathname === "/output.css") {
86
+ const css = await readFile(join(__dirname, "output.css"), "utf-8");
87
+ res.writeHead(200, { "Content-Type": "text/css" });
88
+ res.end(css);
89
+ } else if (req.method === "GET" && url.pathname === "/") {
86
90
  const html = await readFile(join(__dirname, "index.html"), "utf-8");
87
91
  res.writeHead(200, { "Content-Type": "text/html" });
88
92
  res.end(html);