quiver-cli 0.8.0 → 1.1.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.
- package/README.md +127 -45
- package/bin/quiver-cli.mjs +3 -1
- package/dist/cli.js +666 -436
- package/package.json +2 -2
- package/template/.agents/AGENTS.md +4 -3
- package/template/.agents/config.json +7 -0
- package/template/.agents/plugins/opencode/rtk.ts +34 -0
- package/template/.agents/skills/agent-browser/SKILL.md +1 -0
- package/template/.agents/skills/apps/skybridge/SKILL.md +4 -0
- package/template/.agents/skills/design/impeccable/SKILL.md +36 -118
- package/template/.agents/skills/design/impeccable/reference/adapt.md +1 -0
- package/template/.agents/skills/design/impeccable/reference/adapt.native.md +58 -0
- package/template/.agents/skills/design/impeccable/reference/android.md +40 -0
- package/template/.agents/skills/design/impeccable/reference/animate.md +73 -188
- package/template/.agents/skills/design/impeccable/reference/audit.md +12 -9
- package/template/.agents/skills/design/impeccable/reference/audit.native.md +139 -0
- package/template/.agents/skills/design/impeccable/reference/bolder.md +19 -101
- package/template/.agents/skills/design/impeccable/reference/clarify.md +59 -253
- package/template/.agents/skills/design/impeccable/reference/colorize.md +51 -222
- package/template/.agents/skills/design/impeccable/reference/craft-floor.md +42 -0
- package/template/.agents/skills/design/impeccable/reference/craft.md +3 -121
- package/template/.agents/skills/design/impeccable/reference/critique.md +44 -23
- package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +90 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/documenter.md +24 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +37 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/manual-edit-applier.md +92 -0
- package/template/.agents/skills/design/impeccable/reference/delight.md +47 -279
- package/template/.agents/skills/design/impeccable/reference/distill.md +2 -2
- package/template/.agents/skills/design/impeccable/reference/doctor.md +53 -0
- package/template/.agents/skills/design/impeccable/reference/document.md +60 -73
- package/template/.agents/skills/design/impeccable/reference/harden.md +1 -12
- package/template/.agents/skills/design/impeccable/reference/hooks.md +20 -5
- package/template/.agents/skills/design/impeccable/reference/init.md +72 -119
- package/template/.agents/skills/design/impeccable/reference/ios.md +45 -0
- package/template/.agents/skills/design/impeccable/reference/layout.md +54 -131
- package/template/.agents/skills/design/impeccable/reference/live-setup.md +102 -0
- package/template/.agents/skills/design/impeccable/reference/live.md +116 -511
- package/template/.agents/skills/design/impeccable/reference/new-work.md +105 -0
- package/template/.agents/skills/design/impeccable/reference/{product.md → operate.md} +6 -5
- package/template/.agents/skills/design/impeccable/reference/optimize.md +4 -4
- package/template/.agents/skills/design/impeccable/reference/overdrive.md +1 -4
- package/template/.agents/skills/design/impeccable/reference/polish.md +68 -212
- package/template/.agents/skills/design/impeccable/reference/quieter.md +3 -3
- package/template/.agents/skills/design/impeccable/reference/routing.md +18 -0
- package/template/.agents/skills/design/impeccable/reference/shape.md +38 -144
- package/template/.agents/skills/design/impeccable/reference/typeset.md +51 -250
- package/template/.agents/skills/design/impeccable/reference/visualize.md +47 -0
- package/template/.agents/skills/design/impeccable/scripts/command-metadata.json +1 -1
- package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +558 -0
- package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +119 -10
- package/template/.agents/skills/design/impeccable/scripts/context.mjs +534 -45
- package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +18 -47
- package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +96 -10
- package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +174 -26
- package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +233 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +3348 -203
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +102 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +297 -97
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +187 -16
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +41 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/findings.mjs +7 -1
- package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +16 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +207 -38
- package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +3082 -173
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +11 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/fonts.mjs +30 -0
- package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +336 -0
- package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +133 -0
- package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +240 -0
- package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +98 -18
- package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +46 -6
- package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +518 -50
- package/template/.agents/skills/design/impeccable/scripts/hook.mjs +25 -8
- package/template/.agents/skills/design/impeccable/scripts/lib/artifact-schema.mjs +93 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/composition-catalog.mjs +200 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +357 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +27 -7
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +17 -8
- package/template/.agents/skills/design/impeccable/scripts/lib/provider.mjs +5 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +362 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-notice.mjs +169 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +151 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/target-slug.mjs +33 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/template-extensions.mjs +146 -0
- package/template/.agents/skills/design/impeccable/scripts/live/accept-css.mjs +617 -0
- package/template/.agents/skills/design/impeccable/scripts/live/accept-verify.mjs +60 -0
- package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +7 -1
- package/template/.agents/skills/design/impeccable/scripts/live/completion.mjs +10 -1
- package/template/.agents/skills/design/impeccable/scripts/live/event-validation.mjs +67 -5
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/astro.mjs +47 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/detect-utils.mjs +73 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/index.mjs +143 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/journal.mjs +197 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nuxt.mjs +161 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/script-src.mjs +17 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
- package/template/.agents/skills/design/impeccable/scripts/live/generation-preflight.mjs +149 -0
- package/template/.agents/skills/design/impeccable/scripts/live/instructions.mjs +142 -0
- package/template/.agents/skills/design/impeccable/scripts/live/poll-lanes.mjs +14 -0
- package/template/.agents/skills/design/impeccable/scripts/live/roots.mjs +508 -0
- package/template/.agents/skills/design/impeccable/scripts/live/session-store.mjs +324 -50
- package/template/.agents/skills/design/impeccable/scripts/live/source-lock.mjs +105 -0
- package/template/.agents/skills/design/impeccable/scripts/live/source-search.mjs +105 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +961 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +588 -72
- package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +59 -17
- package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +280 -0
- package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +135 -0
- package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +210 -68
- package/template/.agents/skills/design/impeccable/scripts/live-browser.js +1562 -223
- package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +3 -0
- package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +33 -1
- package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +175 -255
- package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +26 -6
- package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +6 -1
- package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +61 -16
- package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +39 -10
- package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +573 -47
- package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +17 -7
- package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +124 -91
- package/template/.agents/skills/design/impeccable/scripts/live.mjs +88 -26
- package/template/.agents/skills/design/impeccable/scripts/palette.mjs +76 -81
- package/template/.agents/skills/design/impeccable/scripts/pin.mjs +18 -11
- package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +932 -0
- package/template/.agents/skills/design/impeccable/scripts/surface-brief.mjs +74 -0
- package/template/.agents/skills/design/shadcn/SKILL.md +46 -11
- package/template/.agents/skills/design/shadcn/cli.md +49 -16
- package/template/.agents/skills/design/shadcn/customization.md +14 -7
- package/template/.agents/skills/design/shadcn/evals/evals.json +30 -0
- package/template/.agents/skills/design/shadcn/mcp.md +27 -16
- package/template/.agents/skills/design/shadcn/registry.md +277 -0
- package/template/.agents/skills/design/shadcn/rules/chat.md +224 -0
- package/template/.agents/skills/design/shadcn/rules/composition.md +20 -2
- package/template/.agents/skills/design/shadcn/rules/styling.md +23 -0
- package/template/.agents/skills/find-skills/SKILL.md +2 -3
- package/template/.agents/skills/hono/SKILL.md +579 -0
- package/template/.agents/skills/integrations/langfuse/SKILL.md +10 -6
- package/template/.agents/skills/integrations/langfuse/references/ci-cd.md +41 -0
- package/template/.agents/skills/integrations/langfuse/references/cli.md +8 -0
- package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +15 -27
- package/template/.agents/skills/integrations/langfuse/references/instrumentation.md +39 -52
- package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +5 -2
- package/template/.agents/skills/integrations/langfuse/references/prompt-engineering.md +35 -0
- package/template/.agents/skills/integrations/langfuse/references/prompt-migration.md +41 -196
- package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +3 -0
- package/template/.agents/skills/integrations/langfuse/references/trace-evaluator-upgrade.md +76 -0
- package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +4 -0
- package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +73 -0
- package/template/.agents/skills/supabase/CHANGELOG.md +71 -0
- package/template/.agents/skills/supabase/SKILL.md +145 -0
- package/template/.agents/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/template/.agents/skills/supabase/references/skill-feedback.md +17 -0
- package/template/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +73 -0
- package/template/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/template/.agents/upstreams.json +34 -12
- package/template/.agents/skills/design/impeccable/reference/brand.md +0 -108
- package/template/.agents/skills/design/impeccable/reference/codex.md +0 -105
- package/template/.agents/skills/design/impeccable/reference/interaction-design.md +0 -189
- package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +0 -175
|
@@ -16,15 +16,59 @@
|
|
|
16
16
|
import fs from 'node:fs';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { isGeneratedFile } from './lib/is-generated.mjs';
|
|
19
|
+
import { getLiveDir, safeSessionId } from './lib/impeccable-paths.mjs';
|
|
20
|
+
import { resolveLiveTemplateExtensions } from './lib/template-extensions.mjs';
|
|
19
21
|
import { readBuffer as readManualEditsBuffer, writeBuffer as writeManualEditsBuffer } from './live/manual-edits-buffer.mjs';
|
|
22
|
+
import { NEVER_SOURCE_DIRS, findSourceFile } from './live/source-search.mjs';
|
|
23
|
+
import { withSourceLockSync } from './live/source-lock.mjs';
|
|
20
24
|
import {
|
|
21
25
|
applyDeferredSvelteComponentAccepts,
|
|
22
26
|
findSvelteComponentManifest,
|
|
23
27
|
inlineSvelteComponentAccept,
|
|
24
28
|
removeSvelteComponentSession,
|
|
25
29
|
} from './live/svelte-component.mjs';
|
|
30
|
+
import { enterLiveRoot } from './live/roots.mjs';
|
|
26
31
|
|
|
27
|
-
const
|
|
32
|
+
const ACCEPT_LOCK_WAIT_MS = 1_000;
|
|
33
|
+
// Mirrors VARIANT_ID_PATTERN in live/event-validation.mjs, which gates the same
|
|
34
|
+
// value arriving over HTTP.
|
|
35
|
+
const VARIANT_NUM_PATTERN = /^[0-9]{1,3}$/;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A thrown accept/discard is a real failure, not a manual handoff.
|
|
39
|
+
*
|
|
40
|
+
* live/completion.mjs only classifies a result as `error` when it carries
|
|
41
|
+
* `mode: 'error'`; anything else unhandled falls through to `agent_done` with a
|
|
42
|
+
* successful ack, and reference/live.md then tells the agent to finish the edit
|
|
43
|
+
* by hand. That is right for the documented fallback paths and wrong here: a
|
|
44
|
+
* `source_locked` contention needs a retry (hand-editing races the publisher
|
|
45
|
+
* holding the lock), and a crash needs surfacing, not a hand-applied guess.
|
|
46
|
+
*/
|
|
47
|
+
function operationFailure(err, extra = {}) {
|
|
48
|
+
return { handled: false, mode: 'error', error: err.message, ...extra };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Mark an unhandled preview-path result as a real failure.
|
|
53
|
+
*
|
|
54
|
+
* operationFailure only covers results built from a *thrown* error. The accept
|
|
55
|
+
* implementations also return `{handled: false, error}` for their own checks
|
|
56
|
+
* (variant missing, template empty, original text ambiguous), and those arrived
|
|
57
|
+
* without `mode`, so completion.mjs classified them as agent_done and
|
|
58
|
+
* reference/live.md routed the agent to "read file, find markers, edit".
|
|
59
|
+
*
|
|
60
|
+
* That handoff only makes sense for a plain wrapper session, which is the one
|
|
61
|
+
* shape with markers in the user's source to edit. Component and isolated
|
|
62
|
+
* artifact previews keep the source clean until Accept, so there is nothing to
|
|
63
|
+
* hand-edit and an unhandled result is always a failure. `previewMode` is
|
|
64
|
+
* exactly that discriminator: only the preview branches set it.
|
|
65
|
+
*/
|
|
66
|
+
function markPreviewFailure(result) {
|
|
67
|
+
if (result?.handled === false && !result.mode && result.previewMode) {
|
|
68
|
+
return { ...result, mode: 'error' };
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
28
72
|
|
|
29
73
|
// ---------------------------------------------------------------------------
|
|
30
74
|
// CLI
|
|
@@ -63,7 +107,52 @@ Output (JSON):
|
|
|
63
107
|
const isDiscard = args.includes('--discard');
|
|
64
108
|
|
|
65
109
|
if (!id) { console.error('Missing --id'); process.exit(1); }
|
|
110
|
+
// `id` becomes a path segment (accept receipts, preview manifests, generated
|
|
111
|
+
// component dirs). Reject separators and traversal here so one check covers
|
|
112
|
+
// every downstream sink.
|
|
113
|
+
try { safeSessionId(id); } catch { console.error('Invalid --id'); process.exit(1); }
|
|
66
114
|
if (!isDiscard && !variantNum) { console.error('Need --discard or --variant N'); process.exit(1); }
|
|
115
|
+
// `variantNum` is interpolated into a RegExp and into the markup written back
|
|
116
|
+
// to source. The browser and the /events schema both constrain it to digits;
|
|
117
|
+
// enforce the same here, or `--variant '.*'` matches the `original` block
|
|
118
|
+
// first and silently accepts the original while reporting success.
|
|
119
|
+
if (!isDiscard && !VARIANT_NUM_PATTERN.test(variantNum)) {
|
|
120
|
+
console.error('Invalid --variant');
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const requestedOperation = isDiscard ? 'discard' : 'accept';
|
|
125
|
+
const priorReceipt = readAcceptReceipt(process.cwd(), id);
|
|
126
|
+
if (priorReceipt) {
|
|
127
|
+
const sameOperation = priorReceipt.operation === requestedOperation
|
|
128
|
+
&& (isDiscard || String(priorReceipt.variantId) === String(variantNum));
|
|
129
|
+
console.log(JSON.stringify(sameOperation
|
|
130
|
+
? { ...priorReceipt.result, handled: true, alreadyApplied: true }
|
|
131
|
+
: {
|
|
132
|
+
// mode: 'error' is what marks this a real failure rather than a manual
|
|
133
|
+
// handoff. Without it, live/completion.mjs classifies the reply as
|
|
134
|
+
// agent_done and reference/live.md tells the agent to "read file, find
|
|
135
|
+
// markers, edit" by hand — which would apply a second, conflicting
|
|
136
|
+
// accept on top of the one the receipt already recorded.
|
|
137
|
+
handled: false,
|
|
138
|
+
mode: 'error',
|
|
139
|
+
error: 'accept_receipt_conflict',
|
|
140
|
+
priorOperation: priorReceipt.operation,
|
|
141
|
+
priorVariantId: priorReceipt.variantId ?? null,
|
|
142
|
+
}));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const emitResult = (rawResult) => {
|
|
146
|
+
const result = markPreviewFailure(rawResult);
|
|
147
|
+
if (result?.handled !== false) {
|
|
148
|
+
writeAcceptReceipt(process.cwd(), id, {
|
|
149
|
+
operation: requestedOperation,
|
|
150
|
+
variantId: isDiscard ? null : String(variantNum),
|
|
151
|
+
result,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
console.log(JSON.stringify(result));
|
|
155
|
+
};
|
|
67
156
|
|
|
68
157
|
let paramValues = null;
|
|
69
158
|
if (paramValuesRaw) {
|
|
@@ -82,39 +171,55 @@ Output (JSON):
|
|
|
82
171
|
|
|
83
172
|
if (svelteComponentManifest) {
|
|
84
173
|
if (isDiscard) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
174
|
+
let result;
|
|
175
|
+
try {
|
|
176
|
+
result = withSourceLockSync(
|
|
177
|
+
path.resolve(process.cwd(), svelteComponentManifest.sourceFile),
|
|
178
|
+
'discard:' + id,
|
|
179
|
+
() => {
|
|
180
|
+
removeSvelteComponentSession(id, process.cwd());
|
|
181
|
+
return { handled: true };
|
|
182
|
+
},
|
|
183
|
+
{ waitMs: ACCEPT_LOCK_WAIT_MS },
|
|
184
|
+
);
|
|
185
|
+
} catch (err) {
|
|
186
|
+
result = operationFailure(err);
|
|
187
|
+
}
|
|
188
|
+
emitResult({
|
|
189
|
+
...result,
|
|
88
190
|
file: svelteComponentManifest.sourceFile,
|
|
89
191
|
carbonize: false,
|
|
90
192
|
previewMode: 'svelte-component',
|
|
91
193
|
componentDir: svelteComponentManifest.componentDir,
|
|
92
|
-
})
|
|
194
|
+
});
|
|
93
195
|
return;
|
|
94
196
|
}
|
|
95
197
|
|
|
96
198
|
let result;
|
|
97
199
|
try {
|
|
98
|
-
result =
|
|
99
|
-
svelteComponentManifest,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
200
|
+
result = withSourceLockSync(
|
|
201
|
+
path.resolve(process.cwd(), svelteComponentManifest.sourceFile),
|
|
202
|
+
'accept:' + id,
|
|
203
|
+
() => inlineSvelteComponentAccept(
|
|
204
|
+
svelteComponentManifest,
|
|
205
|
+
variantNum,
|
|
206
|
+
paramValues,
|
|
207
|
+
process.cwd(),
|
|
208
|
+
),
|
|
209
|
+
{ waitMs: ACCEPT_LOCK_WAIT_MS },
|
|
103
210
|
);
|
|
104
211
|
} catch (err) {
|
|
105
|
-
result = {
|
|
106
|
-
handled: false,
|
|
107
|
-
error: err.message,
|
|
212
|
+
result = operationFailure(err, {
|
|
108
213
|
file: svelteComponentManifest.sourceFile,
|
|
109
214
|
sourceFile: svelteComponentManifest.sourceFile,
|
|
110
215
|
previewMode: 'svelte-component',
|
|
111
216
|
componentDir: svelteComponentManifest.componentDir,
|
|
112
|
-
};
|
|
217
|
+
});
|
|
113
218
|
}
|
|
114
219
|
if (result.carbonize) {
|
|
115
220
|
result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".';
|
|
116
221
|
}
|
|
117
|
-
|
|
222
|
+
emitResult({ handled: result.handled !== false, ...result });
|
|
118
223
|
return;
|
|
119
224
|
}
|
|
120
225
|
|
|
@@ -145,10 +250,25 @@ Output (JSON):
|
|
|
145
250
|
}
|
|
146
251
|
|
|
147
252
|
if (isDiscard) {
|
|
148
|
-
|
|
149
|
-
|
|
253
|
+
let result;
|
|
254
|
+
// handleDiscard takes the source lock, which throws SOURCE_LOCKED under
|
|
255
|
+
// contention. Without this catch the CLI exits non-zero with empty stdout
|
|
256
|
+
// and the agent gets no JSON to act on.
|
|
257
|
+
try {
|
|
258
|
+
result = handleDiscard(id, lines, targetFile);
|
|
259
|
+
} catch (err) {
|
|
260
|
+
emitResult(operationFailure(err, { file: relFile }));
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
emitResult({ handled: true, file: relFile, carbonize: false, ...result });
|
|
150
264
|
} else {
|
|
151
|
-
|
|
265
|
+
let result;
|
|
266
|
+
try {
|
|
267
|
+
result = handleAccept(id, variantNum, lines, targetFile, paramValues);
|
|
268
|
+
} catch (err) {
|
|
269
|
+
emitResult(operationFailure(err, { file: relFile }));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
152
272
|
const acceptedOriginalText = result.acceptedOriginalText || '';
|
|
153
273
|
delete result.acceptedOriginalText;
|
|
154
274
|
// Single-line attention-grabber when cleanup is required. The full
|
|
@@ -167,7 +287,7 @@ Output (JSON):
|
|
|
167
287
|
// Non-fatal; the buffer stays as-is and the user can discard later.
|
|
168
288
|
}
|
|
169
289
|
}
|
|
170
|
-
|
|
290
|
+
emitResult({ handled: true, file: relFile, ...result });
|
|
171
291
|
}
|
|
172
292
|
}
|
|
173
293
|
|
|
@@ -235,7 +355,14 @@ function scrubManualEditsAgainstFile(_targetFile, cwd = process.cwd(), originalB
|
|
|
235
355
|
// Discard
|
|
236
356
|
// ---------------------------------------------------------------------------
|
|
237
357
|
|
|
238
|
-
function handleDiscard(id,
|
|
358
|
+
function handleDiscard(id, _lines, targetFile) {
|
|
359
|
+
return withSourceLockSync(targetFile, 'discard:' + id, () => {
|
|
360
|
+
const lines = fs.readFileSync(targetFile, 'utf-8').split('\n');
|
|
361
|
+
return handleDiscardUnlocked(id, lines, targetFile);
|
|
362
|
+
}, { waitMs: ACCEPT_LOCK_WAIT_MS });
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function handleDiscardUnlocked(id, lines, targetFile) {
|
|
239
366
|
const block = findMarkerBlock(id, lines);
|
|
240
367
|
if (!block) return { handled: false, error: 'Markers not found' };
|
|
241
368
|
|
|
@@ -330,7 +457,24 @@ function reindentContent(contentLines, fromIndent, toIndent) {
|
|
|
330
457
|
});
|
|
331
458
|
}
|
|
332
459
|
|
|
333
|
-
function handleAccept(id, variantNum,
|
|
460
|
+
function handleAccept(id, variantNum, _lines, targetFile, paramValues) {
|
|
461
|
+
return withSourceLockSync(targetFile, 'accept:' + id, () => {
|
|
462
|
+
const lines = fs.readFileSync(targetFile, 'utf-8').split('\n');
|
|
463
|
+
return handleAcceptUnlocked(id, variantNum, lines, targetFile, paramValues);
|
|
464
|
+
}, { waitMs: ACCEPT_LOCK_WAIT_MS });
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function handleAcceptUnlocked(id, variantNum, lines, targetFile, paramValues) {
|
|
468
|
+
const built = buildAcceptedWrappedSource(id, variantNum, lines, targetFile, paramValues);
|
|
469
|
+
if (built.handled === false) return built;
|
|
470
|
+
fs.writeFileSync(targetFile, built.content, 'utf-8');
|
|
471
|
+
return {
|
|
472
|
+
carbonize: built.carbonize,
|
|
473
|
+
acceptedOriginalText: built.acceptedOriginalText,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function buildAcceptedWrappedSource(id, variantNum, lines, targetFile, paramValues) {
|
|
334
478
|
const block = findMarkerBlock(id, lines);
|
|
335
479
|
if (!block) return { handled: false, error: 'Markers not found' };
|
|
336
480
|
|
|
@@ -375,11 +519,14 @@ function handleAccept(id, variantNum, lines, targetFile, paramValues) {
|
|
|
375
519
|
...replacement,
|
|
376
520
|
...lines.slice(replaceRange.end + 1),
|
|
377
521
|
];
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
522
|
+
return {
|
|
523
|
+
content: newLines.join('\n'),
|
|
524
|
+
carbonize: needsCarbonize,
|
|
525
|
+
acceptedOriginalText: originalContent.join('\n'),
|
|
526
|
+
};
|
|
381
527
|
}
|
|
382
528
|
|
|
529
|
+
|
|
383
530
|
function readSourceShadowPreviewMeta(content, id) {
|
|
384
531
|
const escaped = escapeRegExp(id);
|
|
385
532
|
const wrapperRe = new RegExp('<[^>]+data-impeccable-variants=(["\'])' + escaped + '\\1[^>]*>');
|
|
@@ -746,57 +893,51 @@ function detectCommentSyntax(filePath) {
|
|
|
746
893
|
// File search (find the file containing session markers)
|
|
747
894
|
// ---------------------------------------------------------------------------
|
|
748
895
|
|
|
896
|
+
/**
|
|
897
|
+
* Accept also skips `dist` / `build` outright, where wrap descends into them so
|
|
898
|
+
* its `includeGenerated` second pass can report a `generatedMatch`. Accept has
|
|
899
|
+
* no such pass: a marker found in build output is only ever a stale copy of the
|
|
900
|
+
* marker in source.
|
|
901
|
+
*/
|
|
902
|
+
const SEARCH_SKIP_DIRS = [...NEVER_SOURCE_DIRS, 'dist', 'build'];
|
|
903
|
+
|
|
749
904
|
function findSessionFile(id, cwd) {
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
const content = fs.readFileSync(result, 'utf-8');
|
|
760
|
-
return { file: result, content, lines: content.split('\n') };
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
return null;
|
|
905
|
+
const result = findSourceFile({
|
|
906
|
+
query: 'impeccable-variants-start ' + id,
|
|
907
|
+
cwd,
|
|
908
|
+
extensions: resolveLiveTemplateExtensions(cwd),
|
|
909
|
+
skipDirs: SEARCH_SKIP_DIRS,
|
|
910
|
+
});
|
|
911
|
+
if (!result) return null;
|
|
912
|
+
const content = fs.readFileSync(result, 'utf-8');
|
|
913
|
+
return { file: result, content, lines: content.split('\n') };
|
|
764
914
|
}
|
|
765
915
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
try { realDir = fs.realpathSync(dir); } catch { return null; }
|
|
770
|
-
if (seen.has(realDir)) return null;
|
|
771
|
-
seen.add(realDir);
|
|
772
|
-
|
|
773
|
-
let entries;
|
|
774
|
-
try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
|
|
775
|
-
catch { return null; }
|
|
776
|
-
|
|
777
|
-
for (const entry of entries) {
|
|
778
|
-
if (!entry.isFile()) continue;
|
|
779
|
-
if (!EXTENSIONS.includes(path.extname(entry.name).toLowerCase())) continue;
|
|
780
|
-
const filePath = path.join(dir, entry.name);
|
|
781
|
-
try {
|
|
782
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
783
|
-
if (content.includes(query)) return filePath;
|
|
784
|
-
} catch { /* skip */ }
|
|
785
|
-
}
|
|
916
|
+
// ---------------------------------------------------------------------------
|
|
917
|
+
// Utilities
|
|
918
|
+
// ---------------------------------------------------------------------------
|
|
786
919
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
const result = searchDir(path.join(dir, entry.name), query, seen, depth + 1);
|
|
791
|
-
if (result) return result;
|
|
792
|
-
}
|
|
920
|
+
function acceptReceiptPath(cwd, id) {
|
|
921
|
+
return path.join(getLiveDir(cwd), 'accept-receipts', `${safeSessionId(id)}.json`);
|
|
922
|
+
}
|
|
793
923
|
|
|
794
|
-
|
|
924
|
+
function readAcceptReceipt(cwd, id) {
|
|
925
|
+
try { return JSON.parse(fs.readFileSync(acceptReceiptPath(cwd, id), 'utf-8')); } catch { return null; }
|
|
795
926
|
}
|
|
796
927
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
928
|
+
function writeAcceptReceipt(cwd, id, receipt) {
|
|
929
|
+
const file = acceptReceiptPath(cwd, id);
|
|
930
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
931
|
+
const value = {
|
|
932
|
+
id,
|
|
933
|
+
...receipt,
|
|
934
|
+
completedAt: new Date().toISOString(),
|
|
935
|
+
};
|
|
936
|
+
const temporary = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
937
|
+
fs.writeFileSync(temporary, JSON.stringify(value, null, 2) + '\n', 'utf-8');
|
|
938
|
+
fs.renameSync(temporary, file);
|
|
939
|
+
return value;
|
|
940
|
+
}
|
|
800
941
|
|
|
801
942
|
function argVal(args, flag) {
|
|
802
943
|
const idx = args.indexOf(flag);
|
|
@@ -806,6 +947,7 @@ function argVal(args, flag) {
|
|
|
806
947
|
// Auto-execute when run directly
|
|
807
948
|
const _running = process.argv[1];
|
|
808
949
|
if (_running?.endsWith('live-accept.mjs') || _running?.endsWith('live-accept.mjs/')) {
|
|
950
|
+
enterLiveRoot();
|
|
809
951
|
acceptCli();
|
|
810
952
|
}
|
|
811
953
|
|