quiver-cli 0.5.0 → 0.7.0

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/LICENSE +21 -0
  2. package/dist/cli.js +193 -51
  3. package/package.json +1 -1
  4. package/template/.agents/skills/agent-browser/SKILL.md +4 -9
  5. package/template/.agents/skills/apps/skybridge/SKILL.md +1 -1
  6. package/template/.agents/skills/code/improve/SKILL.md +9 -5
  7. package/template/.agents/skills/code/improve/references/audit-playbook.md +10 -10
  8. package/template/.agents/skills/code/improve/references/closing-the-loop.md +4 -3
  9. package/template/.agents/skills/code/improve/references/plan-template.md +5 -0
  10. package/template/.agents/skills/design/impeccable/SKILL.md +14 -24
  11. package/template/.agents/skills/design/impeccable/reference/animate.md +1 -1
  12. package/template/.agents/skills/design/impeccable/reference/bolder.md +1 -1
  13. package/template/.agents/skills/design/impeccable/reference/brand.md +2 -2
  14. package/template/.agents/skills/design/impeccable/reference/colorize.md +1 -1
  15. package/template/.agents/skills/design/impeccable/reference/critique.md +6 -6
  16. package/template/.agents/skills/design/impeccable/reference/delight.md +1 -1
  17. package/template/.agents/skills/design/impeccable/reference/distill.md +1 -1
  18. package/template/.agents/skills/design/impeccable/reference/document.md +1 -1
  19. package/template/.agents/skills/design/impeccable/reference/extract.md +1 -1
  20. package/template/.agents/skills/design/impeccable/reference/hooks.md +90 -0
  21. package/template/.agents/skills/design/impeccable/reference/init.md +5 -5
  22. package/template/.agents/skills/design/impeccable/reference/live.md +16 -16
  23. package/template/.agents/skills/design/impeccable/reference/overdrive.md +1 -1
  24. package/template/.agents/skills/design/impeccable/reference/polish.md +2 -2
  25. package/template/.agents/skills/design/impeccable/reference/quieter.md +1 -1
  26. package/template/.agents/skills/design/impeccable/reference/shape.md +2 -2
  27. package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +1 -1
  28. package/template/.agents/skills/design/impeccable/scripts/context.mjs +724 -33
  29. package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +1 -1
  30. package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +204 -0
  31. package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +57 -11
  32. package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +750 -0
  33. package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +633 -46
  34. package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns.mjs +7 -0
  35. package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +29 -4
  36. package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +43 -10
  37. package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +29 -0
  38. package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +27 -1
  39. package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +1 -1
  40. package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +29 -0
  41. package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +401 -46
  42. package/template/.agents/skills/design/impeccable/scripts/detector/shared/inline-ignores.mjs +148 -0
  43. package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +661 -0
  44. package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +476 -0
  45. package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +1632 -0
  46. package/template/.agents/skills/design/impeccable/scripts/hook.mjs +61 -0
  47. package/template/.agents/skills/design/impeccable/scripts/{design-parser.mjs → lib/design-parser.mjs} +8 -1
  48. package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +638 -0
  49. package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +128 -0
  50. package/template/.agents/skills/design/impeccable/scripts/lib/target-args.mjs +42 -0
  51. package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +49 -0
  52. package/template/.agents/skills/design/impeccable/scripts/{live-event-validation.mjs → live/event-validation.mjs} +6 -5
  53. package/template/.agents/skills/design/impeccable/scripts/live/manual-apply.mjs +939 -0
  54. package/template/.agents/skills/design/impeccable/scripts/live/manual-edit-routes.mjs +357 -0
  55. package/template/.agents/skills/design/impeccable/scripts/{live-manual-edits-buffer.mjs → live/manual-edits-buffer.mjs} +1 -1
  56. package/template/.agents/skills/design/impeccable/scripts/{live-session-store.mjs → live/session-store.mjs} +1 -1
  57. package/template/.agents/skills/design/impeccable/scripts/{live-ui-core.mjs → live/ui-core.mjs} +2 -1
  58. package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +36 -0
  59. package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +3 -3
  60. package/template/.agents/skills/design/impeccable/scripts/live-browser-dom.js +146 -0
  61. package/template/.agents/skills/design/impeccable/scripts/live-browser.js +1456 -599
  62. package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +2 -2
  63. package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +2 -2
  64. package/template/.agents/skills/design/impeccable/scripts/live-discard-manual-edits.mjs +1 -1
  65. package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +35 -9
  66. package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +2 -2
  67. package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +2 -2
  68. package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +18 -13
  69. package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +1 -1
  70. package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +77 -1264
  71. package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +2 -2
  72. package/template/.agents/skills/design/impeccable/scripts/live-target.mjs +30 -0
  73. package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +4 -4
  74. package/template/.agents/skills/design/impeccable/scripts/live.mjs +73 -22
  75. package/template/.agents/skills/writing/humanizer/SKILL.md +621 -0
  76. package/template/.agents/upstreams.json +17 -8
  77. package/template/.agents/skills/apps/skybridge/references/architecture.md +0 -175
  78. package/template/.agents/skills/apps/skybridge/references/copy-template.md +0 -24
  79. package/template/.agents/skills/apps/skybridge/references/csp.md +0 -33
  80. package/template/.agents/skills/apps/skybridge/references/deploy.md +0 -33
  81. package/template/.agents/skills/apps/skybridge/references/discover.md +0 -84
  82. package/template/.agents/skills/apps/skybridge/references/download-file.md +0 -77
  83. package/template/.agents/skills/apps/skybridge/references/fetch-and-render-data.md +0 -151
  84. package/template/.agents/skills/apps/skybridge/references/oauth.md +0 -115
  85. package/template/.agents/skills/apps/skybridge/references/open-external-links.md +0 -71
  86. package/template/.agents/skills/apps/skybridge/references/prompt-llm.md +0 -20
  87. package/template/.agents/skills/apps/skybridge/references/publish.md +0 -19
  88. package/template/.agents/skills/apps/skybridge/references/run-locally.md +0 -51
  89. package/template/.agents/skills/apps/skybridge/references/state-and-context.md +0 -151
  90. package/template/.agents/skills/apps/skybridge/references/ui-guidelines.md +0 -205
  91. package/template/.agents/skills/design/impeccable/scripts/cleanup-deprecated.mjs +0 -284
  92. package/template/.agents/skills/design/impeccable/scripts/impeccable-paths.mjs +0 -126
  93. /package/template/.agents/commands/{tf-readme.md → terraform-readme.md} +0 -0
  94. /package/template/.agents/skills/design/impeccable/scripts/{is-generated.mjs → lib/is-generated.mjs} +0 -0
  95. /package/template/.agents/skills/design/impeccable/scripts/{live-completion.mjs → live/completion.mjs} +0 -0
  96. /package/template/.agents/skills/design/impeccable/scripts/{live-insert-ui.mjs → live/insert-ui.mjs} +0 -0
  97. /package/template/.agents/skills/design/impeccable/scripts/{live-svelte-component.mjs → live/svelte-component.mjs} +0 -0
  98. /package/template/.agents/skills/design/impeccable/scripts/{live-sveltekit-adapter.mjs → live/sveltekit-adapter.mjs} +0 -0
@@ -3,8 +3,8 @@
3
3
  * Print durable recovery status for Impeccable live sessions.
4
4
  */
5
5
 
6
- import { createLiveSessionStore } from './live-session-store.mjs';
7
- import { readLiveServerInfo } from './impeccable-paths.mjs';
6
+ import { createLiveSessionStore } from './live/session-store.mjs';
7
+ import { readLiveServerInfo } from './lib/impeccable-paths.mjs';
8
8
  import { manualApplyResumeHint } from './live-resume.mjs';
9
9
 
10
10
  function readServerInfo() {
@@ -0,0 +1,30 @@
1
+ import path from 'node:path';
2
+ import { resolveProjectRoot } from './context.mjs';
3
+ import { parseTargetPath } from './lib/target-args.mjs';
4
+
5
+ export function resolveLiveTarget(cwd = process.cwd(), args = []) {
6
+ const originalCwd = path.resolve(cwd);
7
+ let targetPath = null;
8
+ try {
9
+ targetPath = parseTargetPath(args, { strict: true });
10
+ } catch (err) {
11
+ if (err?.name === 'TargetArgError') {
12
+ process.stderr.write(`${err.message}\n`);
13
+ process.exit(1);
14
+ }
15
+ throw err;
16
+ }
17
+ const absoluteTargetPath = targetPath
18
+ ? path.isAbsolute(targetPath) ? targetPath : path.resolve(originalCwd, targetPath)
19
+ : null;
20
+ const projectRoot = targetPath
21
+ ? resolveProjectRoot(originalCwd, { targetPath: absoluteTargetPath })
22
+ : originalCwd;
23
+ return {
24
+ originalCwd,
25
+ projectRoot,
26
+ targetPath,
27
+ absoluteTargetPath,
28
+ targetOptions: absoluteTargetPath ? { targetPath: absoluteTargetPath } : {},
29
+ };
30
+ }
@@ -2,7 +2,7 @@
2
2
  * CLI helper: find an element in source and wrap it in a variant container.
3
3
  *
4
4
  * Usage:
5
- * npx impeccable wrap --id SESSION_ID --count N --query "hero-combined-left" [--file path]
5
+ * node <scripts_path>/live-wrap.mjs --id SESSION_ID --count N --query "hero-combined-left" [--file path]
6
6
  *
7
7
  * Searches project files for the element matching the query (class name, ID, or
8
8
  * text snippet), wraps it with the variant scaffolding, and prints the file path
@@ -13,13 +13,13 @@
13
13
 
14
14
  import fs from 'node:fs';
15
15
  import path from 'node:path';
16
- import { isGeneratedFile } from './is-generated.mjs';
17
- import { readBuffer as readManualEditsBuffer } from './live-manual-edits-buffer.mjs';
16
+ import { isGeneratedFile } from './lib/is-generated.mjs';
17
+ import { readBuffer as readManualEditsBuffer } from './live/manual-edits-buffer.mjs';
18
18
  import {
19
19
  buildSvelteComponentCssAuthoring,
20
20
  scaffoldSvelteComponentSession,
21
21
  shouldUseSvelteComponentInjection,
22
- } from './live-svelte-component.mjs';
22
+ } from './live/svelte-component.mjs';
23
23
 
24
24
  const EXTENSIONS = ['.html', '.jsx', '.tsx', '.vue', '.svelte', '.astro'];
25
25
 
@@ -21,14 +21,16 @@ import { execSync } from 'node:child_process';
21
21
  import fs from 'node:fs';
22
22
  import path from 'node:path';
23
23
  import { fileURLToPath } from 'node:url';
24
- import { loadContext } from './context.mjs';
24
+ import { loadContext, resolveTargetSelection } from './context.mjs';
25
25
  import { resolveFiles } from './live-inject.mjs';
26
- import { readLiveServerInfo } from './impeccable-paths.mjs';
26
+ import { readLiveServerInfo } from './lib/impeccable-paths.mjs';
27
+ import { resolveLiveTarget } from './live-target.mjs';
27
28
 
28
29
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
29
30
 
30
31
  async function liveCli() {
31
32
  const args = process.argv.slice(2);
33
+ const liveTarget = resolveLiveTarget(process.cwd(), args);
32
34
 
33
35
  if (args.includes('--help') || args.includes('-h')) {
34
36
  console.log(`Usage: node live.mjs
@@ -38,37 +40,78 @@ Prepare everything for live variant mode in a single command:
38
40
  - Starts (or reuses) the live server in the background
39
41
  - Injects the browser script tag
40
42
  - Reads PRODUCT.md / DESIGN.md for project context
43
+ - In monorepos, choose a child app first; --target <path> is the fallback/manual path
41
44
 
42
45
  On success, prints a JSON blob with:
43
- { ok, serverPort, serverToken, pageFile, hasContext, context }
46
+ { ok, serverPort, serverToken, pageFiles, projectRoot, repoRoot, targetPath, productPath, designPath }
47
+
48
+ On target_selection_required, prints:
49
+ { ok: false, error: "target_selection_required", targetCandidates }
44
50
 
45
51
  On config_missing, prints:
46
52
  { ok: false, error: "config_missing", configPath, hint }
47
53
 
48
54
  The agent should then:
49
- 1. If config_missing, create the config and re-run this script
50
- 2. Optionally open the project's dev/preview URL in the browser (see reference/live.md—not serverPort)
51
- 3. Enter the poll loop: node live-poll.mjs`);
55
+ 1. If target_selection_required, ask which app to use and rerun from that child cwd
56
+ 2. If config_missing, create the config and re-run this script
57
+ 3. Optionally open the project's dev/preview URL in the browser (see reference/live.md—not serverPort)
58
+ 4. Enter the poll loop: node live-poll.mjs`);
59
+ process.exit(0);
60
+ }
61
+
62
+ const targetSelection = resolveTargetSelection(liveTarget.originalCwd, liveTarget.targetOptions);
63
+ if (targetSelection) {
64
+ console.log(JSON.stringify({
65
+ ok: false,
66
+ error: 'target_selection_required',
67
+ ...targetSelection,
68
+ hint: 'Ask the user which app Impeccable should use, then rerun live from that child app cwd. Use --target <path> only as a fallback or explicit path diagnostic.',
69
+ }, null, 2));
70
+ process.exit(0);
71
+ }
72
+
73
+ const ctx = loadContext(liveTarget.originalCwd, liveTarget.targetOptions);
74
+ const activeCwd = ctx.projectRoot;
75
+ const outputTargetPath = liveTarget.targetPath || null;
76
+
77
+ const missingContext = missingLiveContext(ctx);
78
+ if (missingContext.length > 0) {
79
+ console.log(JSON.stringify({
80
+ ok: false,
81
+ error: 'context_missing',
82
+ missing: missingContext,
83
+ nextCommand: missingContext.includes('PRODUCT.md') ? 'init' : 'document',
84
+ targetPath: outputTargetPath,
85
+ projectRoot: ctx.projectRoot,
86
+ repoRoot: ctx.repoRoot,
87
+ productPath: ctx.productPath,
88
+ designPath: ctx.designPath,
89
+ }, null, 2));
52
90
  process.exit(0);
53
91
  }
54
92
 
55
93
  // 1. Check config (fail fast if missing — no point starting anything else)
56
- const checkOut = runScript('live-inject.mjs', ['--check']);
94
+ const checkOut = runScript('live-inject.mjs', ['--check'], { cwd: activeCwd });
57
95
  const checkResult = safeParse(checkOut);
58
96
  if (!checkResult || !checkResult.ok) {
59
- console.log(JSON.stringify(checkResult || { ok: false, error: 'check_failed', raw: checkOut }));
97
+ console.log(JSON.stringify({
98
+ ...(checkResult || { ok: false, error: 'check_failed', raw: checkOut }),
99
+ targetPath: outputTargetPath,
100
+ projectRoot: ctx.projectRoot,
101
+ repoRoot: ctx.repoRoot,
102
+ }));
60
103
  process.exit(0);
61
104
  }
62
105
 
63
106
  // 2. Start server (or reuse existing)
64
- const serverInfo = ensureServerRunning();
107
+ const serverInfo = ensureServerRunning(activeCwd);
65
108
  if (!serverInfo) {
66
109
  console.log(JSON.stringify({ ok: false, error: 'server_start_failed' }));
67
110
  process.exit(1);
68
111
  }
69
112
 
70
113
  // 3. Inject the script tag at the current port
71
- const injectOut = runScript('live-inject.mjs', ['--port', String(serverInfo.port)]);
114
+ const injectOut = runScript('live-inject.mjs', ['--port', String(serverInfo.port)], { cwd: activeCwd });
72
115
  const injectResult = safeParse(injectOut);
73
116
  if (!injectResult || !injectResult.ok) {
74
117
  console.log(JSON.stringify({
@@ -80,22 +123,23 @@ The agent should then:
80
123
  process.exit(1);
81
124
  }
82
125
 
83
- // 4. Load PRODUCT.md + DESIGN.md context.
84
- const ctx = loadContext(process.cwd());
85
-
86
- // 5. Compute drift-heal: compare resolved inject targets against the
126
+ // 4. Compute drift-heal: compare resolved inject targets against the
87
127
  // project's HTML files. Orphans are HTML files not covered by config.
88
128
  // Warning only — the agent decides whether to act.
89
- const resolvedFiles = resolveFiles(process.cwd(), checkResult.config);
90
- const drift = scanForDrift(process.cwd(), resolvedFiles, checkResult.config);
129
+ const resolvedFiles = resolveFiles(activeCwd, checkResult.config);
130
+ const drift = scanForDrift(activeCwd, resolvedFiles, checkResult.config);
91
131
 
92
- // 6. Emit everything the agent needs
132
+ // 5. Emit everything the agent needs
93
133
  console.log(JSON.stringify({
94
134
  ok: true,
95
135
  serverPort: serverInfo.port,
96
136
  serverToken: serverInfo.token,
97
137
  pageFiles: resolvedFiles,
138
+ liveConfigPath: checkResult.path,
98
139
  configDrift: drift,
140
+ targetPath: outputTargetPath,
141
+ projectRoot: ctx.projectRoot,
142
+ repoRoot: ctx.repoRoot,
99
143
  hasProduct: ctx.hasProduct,
100
144
  product: ctx.product,
101
145
  productPath: ctx.productPath,
@@ -105,6 +149,13 @@ The agent should then:
105
149
  }, null, 2));
106
150
  }
107
151
 
152
+ function missingLiveContext(ctx) {
153
+ const missing = [];
154
+ if (!ctx.hasProduct) missing.push('PRODUCT.md');
155
+ if (!ctx.hasDesign) missing.push('DESIGN.md');
156
+ return missing;
157
+ }
158
+
108
159
  /**
109
160
  * Drift-heal scan. Walks the project for HTML files under common
110
161
  * page-source directories (public/, src/, app/, pages/) and reports any
@@ -201,11 +252,11 @@ function globToRegex(pattern) {
201
252
  // Helpers
202
253
  // ---------------------------------------------------------------------------
203
254
 
204
- function runScript(name, args) {
255
+ function runScript(name, args, options = {}) {
205
256
  const scriptPath = path.join(__dirname, name);
206
257
  const cmd = `node "${scriptPath}" ${args.map(a => `"${a}"`).join(' ')}`;
207
258
  try {
208
- return execSync(cmd, { encoding: 'utf-8', cwd: process.cwd(), timeout: 15_000 });
259
+ return execSync(cmd, { encoding: 'utf-8', cwd: options.cwd || process.cwd(), timeout: 15_000 });
209
260
  } catch (err) {
210
261
  // execSync throws on non-zero exit; return stdout if any
211
262
  return err.stdout || err.message || '';
@@ -219,10 +270,10 @@ function safeParse(out) {
219
270
  /**
220
271
  * Return { pid, port, token } for the running live server, starting one if needed.
221
272
  */
222
- function ensureServerRunning() {
273
+ function ensureServerRunning(cwd = process.cwd()) {
223
274
  // Try to reuse an existing server
224
275
  try {
225
- const existing = readLiveServerInfo(process.cwd())?.info;
276
+ const existing = readLiveServerInfo(cwd)?.info;
226
277
  if (existing && existing.pid) {
227
278
  try {
228
279
  process.kill(existing.pid, 0); // throws if dead
@@ -232,7 +283,7 @@ function ensureServerRunning() {
232
283
  } catch { /* no PID file */ }
233
284
 
234
285
  // Start a new server
235
- const out = runScript('live-server.mjs', ['--background']);
286
+ const out = runScript('live-server.mjs', ['--background'], { cwd });
236
287
  return safeParse(out);
237
288
  }
238
289