tux-review 0.1.7 → 0.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tux-review",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "TUX - TUX UIX review system: attach structured, machine-readable feedback directly to running web UIs (pages, routes, components, elements, states) with a deterministic CLI, canonical JSON and LLM-friendly skills.",
5
5
  "license": "MIT",
6
6
  "author": {
package/src/design.js CHANGED
@@ -11,6 +11,7 @@ import { canonicalJson } from './canonical.js';
11
11
  import { CONFIG_FILE, defaultConfig } from './config.js';
12
12
  import { SUPPORTED_FRAMEWORKS, designTemplate } from './templates.js';
13
13
  import { startServer, opLiveStatus, opLiveStop } from './live.js';
14
+ import { deploySkills } from './skills.js';
14
15
 
15
16
  function textReport(lines) {
16
17
  return { stdout: lines.join('\n') + '\n', exit: EXIT.ok };
@@ -40,6 +41,7 @@ export function opDesignInstall(opts, spec) {
40
41
  if (spec.root) config.design.root = spec.root;
41
42
  const root = config.design.root ?? 'requirements';
42
43
  writeFileSync(configPath, canonicalJson(config) + '\n', 'utf8');
44
+ deploySkills(cwd);
43
45
  const report = {
44
46
  action: 'install',
45
47
  kind: 'design',
package/src/live.js CHANGED
@@ -13,6 +13,7 @@ import { CliError, EXIT } from './errors.js';
13
13
  import { canonicalJson } from './canonical.js';
14
14
  import { canonicalTimestamp } from './ids.js';
15
15
  import { loadStore } from './store.js';
16
+ import { deploySkills } from './skills.js';
16
17
 
17
18
  const SERVER_STATE_FILE = '.tux/server.json';
18
19
 
@@ -59,6 +60,7 @@ export function opLiveInstall(opts) {
59
60
  const m = devCommand.match(/--port[= ](\d+)/);
60
61
  if (m) devPort = Number(m[1]);
61
62
  }
63
+ deploySkills(cwd);
62
64
  const report = {
63
65
  action: 'install',
64
66
  kind: 'live',
@@ -87,6 +89,7 @@ export async function startServer(opts, spec) {
87
89
  if (spec.dryRun) {
88
90
  return { stdout: canonicalJson(spec.plan) + '\n', exit: EXIT.ok };
89
91
  }
92
+ deploySkills(opts.cwd);
90
93
  mkdirSync(join(opts.cwd, '.tux'), { recursive: true });
91
94
  let appPid = null;
92
95
  if (spec.cmd) {
package/src/skills.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Canonical skill deployment (SPC sections 28, 32): `tux design install`,
3
+ * `tux live install` and the start-review commands deploy the packaged
4
+ * skills verbatim into the project's agent skill directories, so a package
5
+ * installation plus one CLI invocation leaves the project ready, and a
6
+ * package update refreshes the deployed copies on the next invocation.
7
+ *
8
+ * @module skills
9
+ */
10
+ import { mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
11
+ import { dirname, join } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { CliError, EXIT } from './errors.js';
14
+
15
+ /** Agent skill directories relative to the project root (SPC sections 28, 32). */
16
+ export const AGENT_DIRS = ['.kilo', '.claude', '.hermes'];
17
+
18
+ const packagedSkillsDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'skills');
19
+
20
+ /**
21
+ * Deploy every packaged `tux-<name>.md` skill verbatim into
22
+ * `<root>/<agent>/skills/<name>/SKILL.md` for each agent directory.
23
+ * Idempotent: deployed copies are rewritten on every run; files not
24
+ * shipped by this package are never touched. Returns the sorted names.
25
+ *
26
+ * @param {string} root project root directory
27
+ * @returns {string[]} deployed skill names, sorted
28
+ */
29
+ export function deploySkills(root) {
30
+ const names = readdirSync(packagedSkillsDir)
31
+ .filter((f) => /^tux-.+\.md$/.test(f))
32
+ .sort()
33
+ .map((f) => f.replace(/\.md$/, ''));
34
+ try {
35
+ for (const agent of AGENT_DIRS) {
36
+ for (const name of names) {
37
+ const dst = join(root, agent, 'skills', name, 'SKILL.md');
38
+ mkdirSync(dirname(dst), { recursive: true });
39
+ writeFileSync(dst, readFileSync(join(packagedSkillsDir, `${name}.md`)));
40
+ }
41
+ }
42
+ } catch (e) {
43
+ throw new CliError(EXIT.general, `skill deployment failed: ${e.message}`);
44
+ }
45
+ return names;
46
+ }