refira-cli 0.1.2 → 0.1.3

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 +8 -5
  2. package/dist/index.js +88 -21
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -102,17 +102,19 @@ Options:
102
102
 
103
103
  ---
104
104
 
105
- ### 5. Live Preview & Harness Validation
105
+ ### 5. Live Preview, Push & Harness Validation
106
106
 
107
- #### `refira preview`
107
+ #### `refira push` (or `refira preview`)
108
108
  Inspects an HTML markup file using the Refira Agent Harness. If violations are detected, execution halts with Exit Code 1 and actionable remediation instructions. If valid, the markup is streamed directly to the Refira Canvas.
109
109
 
110
110
  ```bash
111
+ refira push checkout.html --page checkout
112
+ # Alternatively:
111
113
  refira preview checkout.html --page checkout
112
114
  ```
113
115
 
114
116
  Arguments:
115
- - `<file>`: Path to the HTML file to inspect and preview.
117
+ - `<file>`: Path to the HTML file to inspect and push/preview.
116
118
 
117
119
  Options:
118
120
  - `--page <slug>`: Target page slug.
@@ -136,15 +138,16 @@ refira skill install --global
136
138
 
137
139
  ## Agent Harness Invariants
138
140
 
139
- All markup submitted via `refira preview` must conform to these strict architectural rules:
141
+ All markup submitted via `refira push` / `refira preview` must conform to these strict architectural rules:
140
142
 
141
143
  | Rule | Status | Description |
142
144
  |---|---|---|
143
145
  | **Standalone HTML5 + Tailwind** | Required | Markup must be valid native HTML5 with Tailwind CSS utility classes. |
144
146
  | **No UI Frameworks** | Prohibited | React, Vue, Svelte, Angular, Solid, and JSX syntax (`className=`, `onClick={...}`, `<Component />`) are rejected. |
145
- | **No External / Inter-Page Navigation** | Prohibited | Prototypes run inside sandboxed iframes. Anchors (`<a href="...">`) pointing to external URLs or relative pages (e.g. `/checkout`) are rejected. Only in-page anchors (`href="#section"`) or placeholders (`href="#"`) are allowed. |
147
+ | **No External / Inter-Page Navigation** | Prohibited | Prototypes run inside sandboxed iframes. Anchors (`<a href="...">`) pointing to external URLs, relative pages (e.g. `/checkout`), empty `href=""`, or `javascript:` navigation are rejected. Only in-page anchors (`href="#section"`) or placeholders (`href="#"`) are allowed. Target attributes (`target="_blank"`, `target="_top"`) and `<form action="...">` are prohibited. For interactive triggers, use `<button type="button">`. |
146
148
  | **No Raw Emojis in Markup** | Prohibited | Raw unicode emojis (e.g. rocket, fire, sparkles) in HTML text nodes or attributes are rejected to maintain professional aesthetic quality. Use Lucide Icons or Heroicons SVG elements instead. |
147
149
  | **Graphics & Animation Libraries** | Permitted | Standalone CDN scripts such as Three.js, GSAP, Spline Viewer, and Lucide Icons are explicitly allowed in document `<head>` or `<script>`. |
150
+ | **Mandatory Push Execution** | Required | AI agents are strictly forbidden from stopping after writing a local file. The task is only complete when `refira push` succeeds with exit code 0. |
148
151
 
149
152
  ---
150
153
 
package/dist/index.js CHANGED
@@ -1964,6 +1964,19 @@ class CliApiClient {
1964
1964
  const body = await res.json();
1965
1965
  return body.data;
1966
1966
  }
1967
+ async startGenerating(projectId, pageIdentifier) {
1968
+ const url = `${this.apiUrl}/api/cli/projects/${projectId}/pages/${pageIdentifier}/start-generating`;
1969
+ const res = await fetch(url, {
1970
+ method: "POST",
1971
+ headers: this.getHeaders()
1972
+ });
1973
+ if (!res.ok) {
1974
+ const err = await res.text();
1975
+ throw new Error(`Failed to signal generation start (${res.status}): ${err}`);
1976
+ }
1977
+ const body = await res.json();
1978
+ return body.data;
1979
+ }
1967
1980
  }
1968
1981
 
1969
1982
  // src/config.ts
@@ -2119,7 +2132,7 @@ function generateAgentsGuide(opts) {
2119
2132
  1. **Output Format:** Standalone HTML5 + Tailwind CSS CDN only.
2120
2133
  2. **Typography:** Load and use Google Fonts "${opts.fontFamily}".
2121
2134
  3. **No UI Frameworks:** Prohibited from using React, Vue, Svelte, Angular, Solid, or JSX syntax (\`className=\`, \`onClick={...}\`, \`<Component />\`).
2122
- 4. **No Inter-Page Navigation:** Prohibited from using \`<a href="/path">\` or external links. Use in-page section hashes (e.g., \`href="#pricing"\`) or \`href="#"\`.
2135
+ 4. **Strict Anchor & Navigation Invariant:** Prohibited from creating cross-page navigation, external links, empty \`href=""\`, or \`javascript:\` navigation in \`<a href="...">\`. Anchor links MUST point only to in-page section hashes (e.g. \`href="#pricing"\`) or dummy hash (\`href="#"\`). Target attributes (\`target="_blank"\`, \`target="_top"\`) and external \`<form action="...">\` are prohibited. For interactive triggers, use \`<button type="button">\`.
2123
2136
  5. **No Raw Emojis:** Do not include raw emojis (e.g. \uD83D\uDE80, \uD83D\uDCA1, \uD83D\uDD25) in HTML markup. Use SVG icon libraries (Lucide Icons or Heroicons).
2124
2137
  6. **Permitted Graphics:** Three.js, GSAP, Spline Viewer, and Lucide Icons via CDN are explicitly allowed.
2125
2138
 
@@ -2127,18 +2140,26 @@ function generateAgentsGuide(opts) {
2127
2140
 
2128
2141
  ## 2. Refira CLI Command Surface
2129
2142
  - \`refira context\`: Inspect project design tokens, colors, typography, and existing pages.
2130
- - \`refira scaffold --page <slug>\`: Create a clean HTML5 starter template with tokens pre-configured.
2131
- - \`refira preview <file.html> --page <slug>\`: Run the deterministic harness check and stream updates to Refira Canvas.
2143
+ - \`refira scaffold --page <slug>\`: Create a clean HTML5 starter template and trigger live generating indicator on Refira Canvas.
2144
+ - \`refira push <file.html> --page <slug>\` (or \`refira preview\`): Run the deterministic harness check and stream updates to Refira Canvas.
2132
2145
  - \`refira skill install [-g]\`: Re-install the Refira design craftsmanship skill.
2133
2146
 
2134
2147
  ---
2135
2148
 
2136
2149
  ## 3. Mandatory Execution Workflow
2137
2150
  1. Run \`refira context\` to understand the project theme and existing pages.
2138
- 2. Run \`refira scaffold --page <page-name>\` to generate the file.
2151
+ 2. Run \`refira scaffold --page <page-name>\` to register the page and activate live canvas pulse.
2139
2152
  3. Write your UI layout within the specified body slot using Tailwind utility classes.
2140
- 4. Execute \`refira preview <page-name>.html --page <page-name>\`.
2153
+ 4. Execute \`refira push <page-name>.html --page <page-name>\`.
2141
2154
  5. If the CLI exits with code 1, address every listed violation and retry until exit code 0.
2155
+
2156
+ ---
2157
+
2158
+ ## 4. Mandatory Delivery Invariant (Push to Canvas)
2159
+ - **Local HTML files are NOT the final deliverable.** Refira Canvas is the live source of truth.
2160
+ - **Strictly Prohibited:** Stopping, ending your response, or reporting completion to the user after only writing a local HTML file.
2161
+ - **Autonomous Execution:** You MUST execute \`refira push <file.html> --page <slug>\` via your command-line execution tool. Do NOT ask the user to run it manually.
2162
+ - **Success Criteria:** A task is ONLY complete when \`refira push\` succeeds with exit code 0 and streams to Refira Canvas.
2142
2163
  `;
2143
2164
  }
2144
2165
 
@@ -2198,9 +2219,10 @@ When presenting features, data, or product capabilities:
2198
2219
  ## 5. Prototype Workflow in Refira
2199
2220
 
2200
2221
  1. Check current tokens: \`refira context\`
2201
- 2. Generate base page: \`refira scaffold --page <slug>\`
2222
+ 2. Generate base page & trigger canvas pulse: \`refira scaffold --page <slug>\`
2202
2223
  3. Fill layout using Tailwind classes applying the aesthetic principles above.
2203
- 4. Preview on canvas: \`refira preview <slug>.html --page <slug>\`
2224
+ 4. Stream to Refira Canvas: \`refira push <slug>.html --page <slug>\`
2225
+ 5. Mandatory: Never stop after writing local files. Always execute \`refira push\` to complete the task.
2204
2226
  `;
2205
2227
  }
2206
2228
 
@@ -3633,12 +3655,14 @@ function checkTagName(name, violations) {
3633
3655
  }
3634
3656
  function checkAttributes(name, attribs, violations) {
3635
3657
  for (const [attrKey, attrVal] of Object.entries(attribs)) {
3636
- if (attrKey === "className") {
3658
+ const lowerAttr = attrKey.toLowerCase();
3659
+ const lowerTag = name.toLowerCase();
3660
+ if (lowerAttr === "classname") {
3637
3661
  violations.push({
3638
3662
  type: "JSX_ATTRIBUTE",
3639
- target: "className",
3640
- message: `Prohibited JSX attribute 'className' detected on <${name}>.`,
3641
- remediation: `Change 'className' to the standard HTML 'class' attribute.`
3663
+ target: attrKey,
3664
+ message: `Prohibited JSX attribute '${attrKey}' detected on <${name}>.`,
3665
+ remediation: `Change '${attrKey}' to the standard HTML 'class' attribute.`
3642
3666
  });
3643
3667
  }
3644
3668
  if (/^on[A-Z]/.test(attrKey) || attrKey.startsWith("@") || attrKey.startsWith("v-") || attrKey.startsWith("*")) {
@@ -3649,15 +3673,52 @@ function checkAttributes(name, attribs, violations) {
3649
3673
  remediation: "Remove framework event bindings. Use vanilla HTML and minimal vanilla JavaScript if needed."
3650
3674
  });
3651
3675
  }
3652
- if (attrKey === "href" && name.toLowerCase() === "a") {
3676
+ if (lowerAttr.startsWith("on") && (attrVal.includes("location") || attrVal.includes("window.open") || attrVal.includes("history."))) {
3677
+ violations.push({
3678
+ type: "NAVIGATION_PROHIBITED",
3679
+ target: `${attrKey}="${attrVal}"`,
3680
+ message: `Inline navigation script '${attrVal}' detected on <${name}>.`,
3681
+ remediation: "Remove inline navigation scripts. Prototypes run in a sandboxed canvas and cannot navigate across pages."
3682
+ });
3683
+ }
3684
+ if (lowerTag === "a") {
3685
+ if (lowerAttr === "href") {
3686
+ const trimmed = attrVal.trim();
3687
+ const isSafeHash = trimmed.startsWith("#");
3688
+ const isSafeVoid = trimmed === "javascript:void(0)" || trimmed === "javascript:;";
3689
+ if (!isSafeHash && !isSafeVoid) {
3690
+ violations.push({
3691
+ type: "NAVIGATION_PROHIBITED",
3692
+ target: `${attrKey}="${attrVal}"`,
3693
+ message: `Cross-page or external navigation '<a ${attrKey}="${attrVal}">' is strictly prohibited.`,
3694
+ remediation: 'Refira prototypes run in a sandboxed iframe. Anchor links must point to in-page section hashes (e.g. href="#features") or placeholder (href="#"). If you need action triggers, use <button type="button">.'
3695
+ });
3696
+ } else if (trimmed.includes("location") || trimmed.includes("window.open")) {
3697
+ violations.push({
3698
+ type: "NAVIGATION_PROHIBITED",
3699
+ target: `${attrKey}="${attrVal}"`,
3700
+ message: `Navigation statement detected inside href: '${attrVal}'.`,
3701
+ remediation: "Remove navigation statements from href."
3702
+ });
3703
+ }
3704
+ }
3705
+ if (lowerAttr === "target" && attrVal.trim().length > 0) {
3706
+ violations.push({
3707
+ type: "NAVIGATION_PROHIBITED",
3708
+ target: `${attrKey}="${attrVal}"`,
3709
+ message: `Target attribute '${attrKey}="${attrVal}"' on <a> is prohibited.`,
3710
+ remediation: "Remove the target attribute. Prototypes must remain within the Refira Canvas viewport."
3711
+ });
3712
+ }
3713
+ }
3714
+ if (lowerTag === "form" && lowerAttr === "action") {
3653
3715
  const trimmed = attrVal.trim();
3654
- const isInternal = trimmed.startsWith("#") || trimmed.startsWith("javascript:");
3655
- if (!isInternal && trimmed.length > 0) {
3716
+ if (trimmed.length > 0 && !trimmed.startsWith("#") && !trimmed.startsWith("javascript:void")) {
3656
3717
  violations.push({
3657
3718
  type: "NAVIGATION_PROHIBITED",
3658
- target: `href="${attrVal}"`,
3659
- message: `Cross-page or external navigation '<a href="${attrVal}">' is prohibited.`,
3660
- remediation: `Refira prototypes run in a sandboxed iframe. Replace with in-page anchor (e.g. href="#features") or placeholder (href="#").`
3719
+ target: `${attrKey}="${attrVal}"`,
3720
+ message: `Form action '${attrVal}' is prohibited in standalone prototypes.`,
3721
+ remediation: 'Remove or replace form action with action="#" or handle submission client-side without page reload.'
3661
3722
  });
3662
3723
  }
3663
3724
  }
@@ -3929,6 +3990,10 @@ async function scaffoldCommand(opts) {
3929
3990
  }
3930
3991
  colorTokens = parsed;
3931
3992
  }
3993
+ try {
3994
+ await client.startGenerating(config.projectId, pageSlug);
3995
+ console.log(`✨ Activated live generation indicator on Refira Canvas for '${pageSlug}'`);
3996
+ } catch {}
3932
3997
  } catch {}
3933
3998
  }
3934
3999
  const pageName = pageSlug.replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
@@ -3944,8 +4009,10 @@ async function scaffoldCommand(opts) {
3944
4009
  console.log(` Font: ${fontFamily}`);
3945
4010
  console.log(" Slot: <!-- [REFIRA CANVAS SLOT: START] -->");
3946
4011
  console.log(`
3947
- Next step: Edit '${targetPath}', then execute:`);
3948
- console.log(` refira preview ${targetPath} --page ${pageSlug}`);
4012
+ \uD83D\uDEA8 [MANDATORY AGENT COMPLETION GATE]:`);
4013
+ console.log(` 1. Write your UI layout within the designated slot in '${targetPath}'.`);
4014
+ console.log(` 2. You MUST execute: refira push ${targetPath} --page ${pageSlug}`);
4015
+ console.log(" DO NOT stop your response or declare completion until `refira push` succeeds!");
3949
4016
  }
3950
4017
 
3951
4018
  // src/commands/skill.ts
@@ -3967,14 +4034,14 @@ AI coding agents will automatically recognize this skill for high-aesthetic prot
3967
4034
 
3968
4035
  // src/index.ts
3969
4036
  var program2 = new Command2;
3970
- program2.name("refira").description("Refira CLI tool and AI Agent Harness for deterministic prototype generation").version("0.1.2");
4037
+ program2.name("refira").description("Refira CLI tool and AI Agent Harness for deterministic prototype generation").version("0.1.3");
3971
4038
  var auth = program2.command("auth").description("Manage Refira API authentication and sessions");
3972
4039
  auth.command("login").description("Login to Refira using an API key").option("--api-url <url>", "Refira backend API base URL", "http://localhost:3001").option("--api-key <key>", "Project API key (rfr_...)").option("-g, --global", "Save credentials globally in user home directory", false).action(loginCommand);
3973
4040
  auth.command("status").description("Verify and display current Refira authentication session").action(statusCommand);
3974
4041
  program2.command("init").description("Initialize a Refira project workspace, generating AGENTS.md, .cursorrules, and skills").requiredOption("--project-id <id>", "Target project UUID").option("--api-url <url>", "Refira backend API base URL").option("--api-key <key>", "Project API key (rfr_...)").action(initCommand);
3975
4042
  program2.command("context").description("Inspect design tokens, color palette, typography, and page roster").option("--project-id <id>", "Project UUID").action(contextCommand);
3976
4043
  program2.command("scaffold").description("Generate a clean HTML5 + Tailwind starter template for a page").requiredOption("--page <slug>", "Page slug (e.g. checkout, dashboard, landing)").option("--output <path>", "Destination file path").action(scaffoldCommand);
3977
- program2.command("preview").description("Inspect HTML markup with Agent Harness and stream to Refira Canvas").argument("<file>", "Path to HTML file to preview").requiredOption("--page <slug>", "Target page slug").action(previewCommand);
4044
+ program2.command("preview").alias("push").description("Inspect HTML markup with Agent Harness and stream to Refira Canvas").argument("<file>", "Path to HTML file to preview").requiredOption("--page <slug>", "Target page slug").action(previewCommand);
3978
4045
  var skill = program2.command("skill").description("Manage Refira Agent Skills");
3979
4046
  skill.command("install").description("Install the Refira design craftsmanship skill (.agents/skills/refira/SKILL.md)").option("-g, --global", "Install globally into user home directory (~/.agents/skills/refira)", false).action(skillInstallCommand);
3980
4047
  program2.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "refira-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Refira CLI tool and AI Agent Harness for deterministic prototype generation",
5
5
  "type": "module",
6
6
  "bin": {