@constela/cli 0.5.48 → 0.5.50

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 (3) hide show
  1. package/README.md +49 -0
  2. package/dist/index.js +36 -36
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -230,6 +230,55 @@ constela start --port 8080
230
230
 
231
231
  The server binds to `0.0.0.0` by default for deployment compatibility.
232
232
 
233
+ ### constela suggest
234
+
235
+ AI を使って DSL ファイルを分析し、改善提案を取得します。
236
+
237
+ ```bash
238
+ constela suggest <input> [options]
239
+ ```
240
+
241
+ **Arguments:**
242
+ - `<input>` - 分析対象の JSON ファイル
243
+
244
+ **Options:**
245
+ - `--aspect <type>` - 分析観点: accessibility, performance, security, ux (default: accessibility)
246
+ - `--provider <name>` - AI プロバイダー: anthropic, openai (default: anthropic)
247
+ - `--json` - JSON 形式で出力
248
+
249
+ **環境変数:**
250
+ - `ANTHROPIC_API_KEY` - Anthropic プロバイダー使用時
251
+ - `OPENAI_API_KEY` - OpenAI プロバイダー使用時
252
+
253
+ **Examples:**
254
+
255
+ ```bash
256
+ # アクセシビリティの分析
257
+ constela suggest app.json --aspect accessibility
258
+
259
+ # セキュリティの分析(OpenAI 使用)
260
+ constela suggest app.json --aspect security --provider openai
261
+
262
+ # JSON 出力
263
+ constela suggest app.json --aspect ux --json
264
+ ```
265
+
266
+ **Output:**
267
+
268
+ ```
269
+ === Suggestions for app.json (accessibility) ===
270
+
271
+ [HIGH] Missing aria-label on button
272
+ Recommendation: Add aria-label="Submit form" to the button element
273
+ Location: view.children[0].props
274
+
275
+ [MED] Low color contrast in text
276
+ Recommendation: Increase contrast ratio to meet WCAG AA standards
277
+ Location: view.children[2].props.style
278
+
279
+ Total: 2 suggestion(s)
280
+ ```
281
+
233
282
  ## Project Structure
234
283
 
235
284
  The CLI expects the following project structure:
package/dist/index.js CHANGED
@@ -23,16 +23,17 @@ var colors = {
23
23
  yellow: (s) => `\x1B[33m${s}\x1B[0m`,
24
24
  reset: "\x1B[0m"
25
25
  };
26
+ var noColors = {
27
+ red: (s) => s,
28
+ green: (s) => s,
29
+ yellow: (s) => s,
30
+ reset: ""
31
+ };
26
32
  function getColors() {
27
33
  if (shouldUseColors()) {
28
34
  return colors;
29
35
  }
30
- return {
31
- red: (s) => s,
32
- green: (s) => s,
33
- yellow: (s) => s,
34
- reset: ""
35
- };
36
+ return noColors;
36
37
  }
37
38
  function countViewNodes(node) {
38
39
  let count = 1;
@@ -51,7 +52,7 @@ function countViewNodes(node) {
51
52
  }
52
53
  break;
53
54
  case "each":
54
- count += countViewNodes(node.template);
55
+ count += countViewNodes(node.body);
55
56
  break;
56
57
  // text, markdown, code, slot nodes have no children
57
58
  default:
@@ -423,7 +424,7 @@ function outputResult(inputPath, result, options, c) {
423
424
  }
424
425
  async function compileCommand(inputPath, options) {
425
426
  const isJsonMode = options.json === true;
426
- const c = isJsonMode ? { red: (s) => s, green: (s) => s, yellow: (s) => s, reset: "" } : getColors();
427
+ const c = isJsonMode ? noColors : getColors();
427
428
  const result = performCompilation(inputPath, options, c);
428
429
  outputResult(inputPath, result, options, c);
429
430
  if (!options.watch) {
@@ -470,16 +471,17 @@ var colors2 = {
470
471
  yellow: (s) => `\x1B[33m${s}\x1B[0m`,
471
472
  reset: "\x1B[0m"
472
473
  };
474
+ var noColors2 = {
475
+ red: (s) => s,
476
+ green: (s) => s,
477
+ yellow: (s) => s,
478
+ reset: ""
479
+ };
473
480
  function getColors2() {
474
481
  if (shouldUseColors2()) {
475
482
  return colors2;
476
483
  }
477
- return {
478
- red: (s) => s,
479
- green: (s) => s,
480
- yellow: (s) => s,
481
- reset: ""
482
- };
484
+ return noColors2;
483
485
  }
484
486
  function formatColoredError2(error, c) {
485
487
  const lines = [];
@@ -573,7 +575,7 @@ async function validateCommand(input, options) {
573
575
  const startTime = performance.now();
574
576
  const isJsonMode = options.json === true;
575
577
  const isAllMode = options.all === true;
576
- const c = isJsonMode ? { red: (s) => s, green: (s) => s, yellow: (s) => s, reset: "" } : getColors2();
578
+ const c = isJsonMode ? noColors2 : getColors2();
577
579
  function exitWithResult(success, output) {
578
580
  if (isJsonMode && output) {
579
581
  outputJson2(output);
@@ -730,18 +732,19 @@ var colors3 = {
730
732
  dim: (s) => `\x1B[2m${s}\x1B[0m`,
731
733
  reset: "\x1B[0m"
732
734
  };
735
+ var noColors3 = {
736
+ red: (s) => s,
737
+ green: (s) => s,
738
+ yellow: (s) => s,
739
+ cyan: (s) => s,
740
+ dim: (s) => s,
741
+ reset: ""
742
+ };
733
743
  function getColors3() {
734
744
  if (shouldUseColors3()) {
735
745
  return colors3;
736
746
  }
737
- return {
738
- red: (s) => s,
739
- green: (s) => s,
740
- yellow: (s) => s,
741
- cyan: (s) => s,
742
- dim: (s) => s,
743
- reset: ""
744
- };
747
+ return noColors3;
745
748
  }
746
749
  function summarizeStep(step) {
747
750
  switch (step.do) {
@@ -772,13 +775,14 @@ function summarizeStep(step) {
772
775
  }
773
776
  }
774
777
  function summarizeAction(action) {
775
- if (action.steps.length === 0) {
778
+ const firstStep = action.steps[0];
779
+ if (!firstStep) {
776
780
  return "(empty)";
777
781
  }
778
782
  if (action.steps.length === 1) {
779
- return summarizeStep(action.steps[0]);
783
+ return summarizeStep(firstStep);
780
784
  }
781
- return `${summarizeStep(action.steps[0])} + ${action.steps.length - 1} more`;
785
+ return `${summarizeStep(firstStep)} + ${action.steps.length - 1} more`;
782
786
  }
783
787
  function viewNodeToInfo(node) {
784
788
  const info = { kind: node.kind };
@@ -979,14 +983,7 @@ function formatViewSection(view, c) {
979
983
  }
980
984
  async function inspectCommand(input, options) {
981
985
  const isJsonMode = options.json === true;
982
- const c = isJsonMode ? {
983
- red: (s) => s,
984
- green: (s) => s,
985
- yellow: (s) => s,
986
- cyan: (s) => s,
987
- dim: (s) => s,
988
- reset: ""
989
- } : getColors3();
986
+ const c = isJsonMode ? noColors3 : getColors3();
990
987
  const showAll = !options.state && !options.actions && !options.components && !options.view;
991
988
  const showState = showAll || options.state === true;
992
989
  const showActions = showAll || options.actions === true;
@@ -1058,8 +1055,11 @@ async function inspectCommand(input, options) {
1058
1055
  sections.push(formatViewSection(program2.view, c));
1059
1056
  }
1060
1057
  for (let i = 0; i < sections.length; i++) {
1061
- for (const line of sections[i]) {
1062
- console.log(line);
1058
+ const section = sections[i];
1059
+ if (section) {
1060
+ for (const line of section) {
1061
+ console.log(line);
1062
+ }
1063
1063
  }
1064
1064
  if (i < sections.length - 1) {
1065
1065
  console.log("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/cli",
3
- "version": "0.5.48",
3
+ "version": "0.5.50",
4
4
  "description": "CLI tools for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,10 +19,10 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "commander": "^12.0.0",
22
- "@constela/core": "0.16.2",
23
- "@constela/start": "1.8.26",
24
- "@constela/ai": "1.0.2",
25
- "@constela/compiler": "0.14.7"
22
+ "@constela/ai": "2.0.0",
23
+ "@constela/compiler": "0.15.0",
24
+ "@constela/start": "1.9.0",
25
+ "@constela/core": "0.17.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^20.10.0",