quiver-cli 1.2.0 → 1.3.1
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/dist/cli.js +237 -10
- package/package.json +1 -1
- package/template/.agents/skills/agent-browser/SKILL.md +1 -0
- package/template/.agents/skills/apps/skybridge/SKILL.md +2 -0
- package/template/.agents/skills/data/prisma-cli/SKILL.md +25 -7
- package/template/.agents/skills/data/prisma-cli/references/agent-safety.md +27 -0
- package/template/.agents/skills/data/prisma-cli/references/complete.md +22 -0
- package/template/.agents/skills/data/prisma-cli/references/db-push.md +2 -0
- package/template/.agents/skills/data/prisma-cli/references/init.md +3 -0
- package/template/.agents/skills/data/prisma-cli/references/mcp.md +2 -1
- package/template/.agents/skills/data/prisma-cli/references/migrate-dev.md +1 -1
- package/template/.agents/skills/data/prisma-cli/references/migrate-reset.md +2 -0
- package/template/.agents/skills/data/prisma-client-api/SKILL.md +1 -1
- package/template/.agents/skills/data/prisma-client-api/references/constructor.md +13 -0
- package/template/.agents/skills/data/prisma-client-api/references/raw-queries.md +4 -0
- package/template/.agents/skills/design/impeccable/SKILL.md +5 -5
- package/template/.agents/skills/design/impeccable/reference/android.md +6 -0
- package/template/.agents/skills/design/impeccable/reference/animate.md +3 -0
- package/template/.agents/skills/design/impeccable/reference/bolder.md +3 -1
- package/template/.agents/skills/design/impeccable/reference/craft-floor.md +2 -0
- package/template/.agents/skills/design/impeccable/reference/critique.md +23 -5
- package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +15 -68
- package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +13 -12
- package/template/.agents/skills/design/impeccable/reference/distill.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/doctor.md +1 -0
- package/template/.agents/skills/design/impeccable/reference/document.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/extract.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/hooks.md +17 -11
- package/template/.agents/skills/design/impeccable/reference/init.md +9 -3
- package/template/.agents/skills/design/impeccable/reference/ios.md +6 -0
- package/template/.agents/skills/design/impeccable/reference/new-work.md +69 -29
- package/template/.agents/skills/design/impeccable/reference/overdrive.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/polish.md +13 -5
- package/template/.agents/skills/design/impeccable/reference/quieter.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/routing.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/visualize.md +21 -22
- package/template/.agents/skills/design/impeccable/scripts/build-phase.mjs +1022 -0
- package/template/.agents/skills/design/impeccable/scripts/comp-diff.mjs +391 -0
- package/template/.agents/skills/design/impeccable/scripts/comp-spec.mjs +513 -0
- package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +297 -41
- package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +10 -19
- package/template/.agents/skills/design/impeccable/scripts/context.mjs +124 -9
- package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +279 -19
- package/template/.agents/skills/design/impeccable/scripts/data/font-index-failures.json +121 -0
- package/template/.agents/skills/design/impeccable/scripts/data/font-index.json +1 -0
- package/template/.agents/skills/design/impeccable/scripts/detect.mjs +9 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +192 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +10 -16
- package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +339 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +1482 -722
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns.mjs +1 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +64 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +580 -29
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +62 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +31 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +23 -22
- package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +18 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +471 -370
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/color.mjs +474 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +17 -2
- package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +14 -21
- package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +81 -48
- package/template/.agents/skills/design/impeccable/scripts/font-match.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +219 -12
- package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +93 -15
- package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +41 -19
- package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +507 -117
- package/template/.agents/skills/design/impeccable/scripts/hook.mjs +10 -9
- package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +40 -1
- package/template/.agents/skills/design/impeccable/scripts/lib/design-parser.mjs +120 -82
- package/template/.agents/skills/design/impeccable/scripts/lib/font-fingerprint.mjs +564 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/font-index.mjs +130 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/hero-checks.mjs +246 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/image-metrics.mjs +306 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +41 -59
- package/template/.agents/skills/design/impeccable/scripts/lib/is-generated.mjs +5 -2
- package/template/.agents/skills/design/impeccable/scripts/lib/live-path-globs.mjs +37 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/open-system-browser.mjs +26 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/png.mjs +281 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/raster.mjs +194 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +26 -19
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +31 -3
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +93 -17
- package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +9 -11
- package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +31 -2
- package/template/.agents/skills/design/impeccable/scripts/live/project-ignores.mjs +139 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +10 -2
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +26 -2
- package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +15 -27
- package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +4 -25
- package/template/.agents/skills/design/impeccable/scripts/live/ui-surfaces.mjs +75 -0
- package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +21 -37
- package/template/.agents/skills/design/impeccable/scripts/live-browser-ignores.js +242 -0
- package/template/.agents/skills/design/impeccable/scripts/live-browser.js +62 -23
- package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +68 -112
- package/template/.agents/skills/design/impeccable/scripts/live-copy-edit-agent.mjs +132 -15
- package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +2 -42
- package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +5 -4
- package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +56 -19
- package/template/.agents/skills/design/impeccable/scripts/live.mjs +12 -37
- package/template/.agents/skills/design/impeccable/scripts/pin.mjs +8 -5
- package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +1006 -155
- package/template/.agents/skills/design/shadcn/rules/chat.md +26 -0
- package/template/.agents/skills/hono/SKILL.md +17 -3
- package/template/.agents/skills/integrations/langfuse/SKILL.md +8 -4
- package/template/.agents/skills/integrations/langfuse/references/cli.md +1 -1
- package/template/.agents/skills/integrations/langfuse/references/create-dataset.md +35 -0
- package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +9 -10
- package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +8 -6
- package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +34 -0
- package/template/.agents/skills/integrations/langfuse/references/setting-up-evals.md +65 -0
- package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +20 -40
- package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +4 -30
- package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +3 -1
- package/template/.agents/skills/supabase/CHANGELOG.md +7 -0
- package/template/.agents/skills/supabase/SKILL.md +5 -1
- package/template/.agents/skills/writing/humanizer/LICENSE +21 -0
- package/template/.agents/skills/writing/humanizer/README.md +209 -0
- package/template/.agents/skills/writing/humanizer/SKILL.md +173 -338
- package/template/.agents/upstreams.json +21 -22
- package/template/.agents/skills/design/impeccable/scripts/live/ui-core.mjs +0 -180
|
@@ -944,8 +944,42 @@ export async function commitManualEdits({
|
|
|
944
944
|
};
|
|
945
945
|
}
|
|
946
946
|
|
|
947
|
+
const repairContext = {
|
|
948
|
+
batch,
|
|
949
|
+
cwd,
|
|
950
|
+
pageUrl,
|
|
951
|
+
count,
|
|
952
|
+
provider,
|
|
953
|
+
env,
|
|
954
|
+
timeoutMs,
|
|
955
|
+
applyBatchToSource,
|
|
956
|
+
chatAvailable,
|
|
957
|
+
transactionId,
|
|
958
|
+
};
|
|
959
|
+
|
|
947
960
|
const baseRollbackScope = collectApplyOwnedFiles(batch, cwd);
|
|
948
961
|
const rollbackSnapshot = snapshotRollbackFiles(cwd, baseRollbackScope);
|
|
962
|
+
const failWithRollback = ({
|
|
963
|
+
scope = baseRollbackScope,
|
|
964
|
+
extraFiles = [],
|
|
965
|
+
failed,
|
|
966
|
+
files = [],
|
|
967
|
+
details = {},
|
|
968
|
+
}) => {
|
|
969
|
+
const rollback = rollbackChangedFiles(cwd, rollbackSnapshot, extraFiles, scope);
|
|
970
|
+
return {
|
|
971
|
+
applied: [],
|
|
972
|
+
failed,
|
|
973
|
+
files,
|
|
974
|
+
cleared: 0,
|
|
975
|
+
count,
|
|
976
|
+
pageUrl,
|
|
977
|
+
...details,
|
|
978
|
+
rolledBackFiles: rollback.rolledBackFiles,
|
|
979
|
+
rollbackFailures: rollback.rollbackFailures,
|
|
980
|
+
...countByPage(cwd),
|
|
981
|
+
};
|
|
982
|
+
};
|
|
949
983
|
let result;
|
|
950
984
|
try {
|
|
951
985
|
result = repairOnly
|
|
@@ -965,42 +999,27 @@ export async function commitManualEdits({
|
|
|
965
999
|
chatAvailable,
|
|
966
1000
|
});
|
|
967
1001
|
} catch (err) {
|
|
968
|
-
|
|
969
|
-
return {
|
|
970
|
-
applied: [],
|
|
1002
|
+
return failWithRollback({
|
|
971
1003
|
failed: batch.entries.map((entry) => ({
|
|
972
1004
|
id: entry.id,
|
|
973
1005
|
reason: err.message || String(err),
|
|
974
1006
|
candidates: candidatesForEntry(batch, entry.id),
|
|
975
1007
|
})),
|
|
976
|
-
|
|
977
|
-
cleared: 0,
|
|
978
|
-
count,
|
|
979
|
-
pageUrl,
|
|
980
|
-
rolledBackFiles: rollback.rolledBackFiles,
|
|
981
|
-
rollbackFailures: rollback.rollbackFailures,
|
|
982
|
-
...countByPage(cwd),
|
|
983
|
-
};
|
|
1008
|
+
});
|
|
984
1009
|
}
|
|
985
1010
|
|
|
986
1011
|
if (result.status === 'error') {
|
|
987
1012
|
const rollbackScope = collectApplyOwnedFiles(batch, cwd, result.files || []);
|
|
988
|
-
const rollback = rollbackChangedFiles(cwd, rollbackSnapshot, result.files || [], rollbackScope);
|
|
989
1013
|
const failed = normalizeFailedEntries(batch, result, result.message || 'AI copy edit failed');
|
|
990
|
-
return {
|
|
991
|
-
|
|
1014
|
+
return failWithRollback({
|
|
1015
|
+
scope: rollbackScope,
|
|
1016
|
+
extraFiles: result.files || [],
|
|
992
1017
|
failed: failed.length > 0
|
|
993
1018
|
? failed
|
|
994
1019
|
: verificationFailuresForEntries(batch, batch.entries, result.message || 'AI copy edit failed'),
|
|
995
1020
|
files: result.files || [],
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
pageUrl,
|
|
999
|
-
notes: result.notes || [],
|
|
1000
|
-
rolledBackFiles: rollback.rolledBackFiles,
|
|
1001
|
-
rollbackFailures: rollback.rollbackFailures,
|
|
1002
|
-
...countByPage(cwd),
|
|
1003
|
-
};
|
|
1021
|
+
details: { notes: result.notes || [] },
|
|
1022
|
+
});
|
|
1004
1023
|
}
|
|
1005
1024
|
|
|
1006
1025
|
const reportedAppliedIds = uniqueStrings(result.appliedEntryIds || []);
|
|
@@ -1013,72 +1032,44 @@ export async function commitManualEdits({
|
|
|
1013
1032
|
const conflictingAppliedIds = reportedAppliedIds.filter((id) => failedIds.has(id));
|
|
1014
1033
|
|
|
1015
1034
|
if (conflictingAppliedIds.length > 0) {
|
|
1016
|
-
const rollback = rollbackChangedFiles(cwd, rollbackSnapshot, result.files || [], rollbackScope);
|
|
1017
1035
|
const conflictingEntries = batch.entries.filter((entry) => conflictingAppliedIds.includes(entry.id));
|
|
1018
|
-
return {
|
|
1019
|
-
|
|
1036
|
+
return failWithRollback({
|
|
1037
|
+
scope: rollbackScope,
|
|
1038
|
+
extraFiles: result.files || [],
|
|
1020
1039
|
failed: [
|
|
1021
1040
|
...verificationFailuresForEntries(batch, conflictingEntries, 'conflicting_apply_result'),
|
|
1022
1041
|
...aiFailed.filter((item) => !conflictingAppliedIds.includes(item.id)),
|
|
1023
1042
|
],
|
|
1024
1043
|
files: result.files || [],
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
pageUrl,
|
|
1028
|
-
notes: result.notes || [],
|
|
1029
|
-
rolledBackFiles: rollback.rolledBackFiles,
|
|
1030
|
-
rollbackFailures: rollback.rollbackFailures,
|
|
1031
|
-
...countByPage(cwd),
|
|
1032
|
-
};
|
|
1044
|
+
details: { notes: result.notes || [] },
|
|
1045
|
+
});
|
|
1033
1046
|
}
|
|
1034
1047
|
|
|
1035
1048
|
const unreportedFiles = unreportedChangedFiles(cwd, rollbackSnapshot, result.files || [], rollbackScope);
|
|
1036
1049
|
if (unreportedFiles.length > 0) {
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1050
|
+
return failWithRollback({
|
|
1051
|
+
scope: [...rollbackScope, ...unreportedFiles],
|
|
1052
|
+
extraFiles: result.files || [],
|
|
1040
1053
|
failed: verificationFailuresForEntries(batch, batch.entries, 'unreported_source_changes', { files: unreportedFiles }),
|
|
1041
1054
|
files: result.files || [],
|
|
1042
|
-
unreportedFiles,
|
|
1043
|
-
|
|
1044
|
-
count,
|
|
1045
|
-
pageUrl,
|
|
1046
|
-
notes: result.notes || [],
|
|
1047
|
-
rolledBackFiles: rollback.rolledBackFiles,
|
|
1048
|
-
rollbackFailures: rollback.rollbackFailures,
|
|
1049
|
-
...countByPage(cwd),
|
|
1050
|
-
};
|
|
1055
|
+
details: { unreportedFiles, notes: result.notes || [] },
|
|
1056
|
+
});
|
|
1051
1057
|
}
|
|
1052
1058
|
|
|
1053
1059
|
if (result.status === 'done' && reportedAppliedIds.length === 0) {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1060
|
+
return failWithRollback({
|
|
1061
|
+
scope: rollbackScope,
|
|
1062
|
+
extraFiles: result.files || [],
|
|
1057
1063
|
failed: verificationFailuresForEntries(batch, batch.entries, 'missing_applied_entry_ids'),
|
|
1058
1064
|
files: result.files || [],
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
pageUrl,
|
|
1062
|
-
notes: result.notes || [],
|
|
1063
|
-
rolledBackFiles: rollback.rolledBackFiles,
|
|
1064
|
-
rollbackFailures: rollback.rollbackFailures,
|
|
1065
|
-
...countByPage(cwd),
|
|
1066
|
-
};
|
|
1065
|
+
details: { notes: result.notes || [] },
|
|
1066
|
+
});
|
|
1067
1067
|
}
|
|
1068
1068
|
|
|
1069
1069
|
const reportedAppliedEntries = batch.entries.filter((entry) => reportedAppliedIds.includes(entry.id));
|
|
1070
1070
|
if (reportedAppliedIds.length > 0 && reportedFiles.length === 0) {
|
|
1071
1071
|
return repairPostApplyValidation({
|
|
1072
|
-
|
|
1073
|
-
cwd,
|
|
1074
|
-
pageUrl,
|
|
1075
|
-
count,
|
|
1076
|
-
provider,
|
|
1077
|
-
env,
|
|
1078
|
-
timeoutMs,
|
|
1079
|
-
applyBatchToSource,
|
|
1080
|
-
chatAvailable,
|
|
1081
|
-
transactionId,
|
|
1072
|
+
...repairContext,
|
|
1082
1073
|
appliedEntryIds: reportedAppliedIds,
|
|
1083
1074
|
files: result.files || [],
|
|
1084
1075
|
failed: aiFailed,
|
|
@@ -1089,21 +1080,10 @@ export async function commitManualEdits({
|
|
|
1089
1080
|
});
|
|
1090
1081
|
}
|
|
1091
1082
|
|
|
1092
|
-
const
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
if (failures.length === 0) {
|
|
1097
|
-
verifiedAppliedIds.push(entry.id);
|
|
1098
|
-
} else {
|
|
1099
|
-
verificationFailed.push({
|
|
1100
|
-
id: entry.id,
|
|
1101
|
-
reason: 'source_verification_failed',
|
|
1102
|
-
failures,
|
|
1103
|
-
candidates: candidatesForEntry(batch, entry.id),
|
|
1104
|
-
});
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1083
|
+
const {
|
|
1084
|
+
verifiedIds: verifiedAppliedIds,
|
|
1085
|
+
failed: verificationFailed,
|
|
1086
|
+
} = verifyEntriesAfterRepair({ batch, appliedEntryIds: reportedAppliedIds, files: reportedFiles, cwd });
|
|
1107
1087
|
const unreportedEntries = result.status === 'done' || result.status === 'partial'
|
|
1108
1088
|
? batch.entries.filter((entry) => !reportedAppliedIds.includes(entry.id) && !aiFailed.some((item) => item.id === entry.id))
|
|
1109
1089
|
: [];
|
|
@@ -1133,37 +1113,22 @@ export async function commitManualEdits({
|
|
|
1133
1113
|
reason: 'rolled_back_due_to_failed_entry_source_changed',
|
|
1134
1114
|
candidates: candidatesForEntry(batch, entry.id),
|
|
1135
1115
|
}));
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1116
|
+
return failWithRollback({
|
|
1117
|
+
scope: rollbackScope,
|
|
1118
|
+
extraFiles: result.files || [],
|
|
1139
1119
|
failed: [
|
|
1140
1120
|
...leakedUnapplied,
|
|
1141
1121
|
...failed.filter((item) => !leakedIds.has(item.id)),
|
|
1142
1122
|
...rolledBackVerified,
|
|
1143
1123
|
],
|
|
1144
1124
|
files: result.files || [],
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
pageUrl,
|
|
1148
|
-
rolledBackFiles: rollback.rolledBackFiles,
|
|
1149
|
-
rollbackFailures: rollback.rollbackFailures,
|
|
1150
|
-
notes: result.notes || [],
|
|
1151
|
-
...countByPage(cwd),
|
|
1152
|
-
};
|
|
1125
|
+
details: { notes: result.notes || [] },
|
|
1126
|
+
});
|
|
1153
1127
|
}
|
|
1154
1128
|
|
|
1155
1129
|
if (verificationFailed.length > 0) {
|
|
1156
1130
|
return repairPostApplyValidation({
|
|
1157
|
-
|
|
1158
|
-
cwd,
|
|
1159
|
-
pageUrl,
|
|
1160
|
-
count,
|
|
1161
|
-
provider,
|
|
1162
|
-
env,
|
|
1163
|
-
timeoutMs,
|
|
1164
|
-
applyBatchToSource,
|
|
1165
|
-
chatAvailable,
|
|
1166
|
-
transactionId,
|
|
1131
|
+
...repairContext,
|
|
1167
1132
|
appliedEntryIds: reportedAppliedIds,
|
|
1168
1133
|
files: result.files || [],
|
|
1169
1134
|
failed: nonRepairFailed,
|
|
@@ -1180,16 +1145,7 @@ export async function commitManualEdits({
|
|
|
1180
1145
|
? reportedAppliedEntries.filter((entry) => verifiedAppliedIds.includes(entry.id))
|
|
1181
1146
|
: batch.entries;
|
|
1182
1147
|
return repairPostApplyValidation({
|
|
1183
|
-
|
|
1184
|
-
cwd,
|
|
1185
|
-
pageUrl,
|
|
1186
|
-
count,
|
|
1187
|
-
provider,
|
|
1188
|
-
env,
|
|
1189
|
-
timeoutMs,
|
|
1190
|
-
applyBatchToSource,
|
|
1191
|
-
chatAvailable,
|
|
1192
|
-
transactionId,
|
|
1148
|
+
...repairContext,
|
|
1193
1149
|
appliedEntryIds: verifiedAppliedIds.length > 0
|
|
1194
1150
|
? verifiedAppliedIds
|
|
1195
1151
|
: postCheckEntries.map((entry) => entry.id).filter(Boolean),
|
|
@@ -14,10 +14,12 @@ import path from 'node:path';
|
|
|
14
14
|
import { createRequire } from 'node:module';
|
|
15
15
|
|
|
16
16
|
const DEFAULT_TIMEOUT_MS = 60_000;
|
|
17
|
+
const BATCH_OP_TEXT_LIMIT = 240;
|
|
17
18
|
const require = createRequire(import.meta.url);
|
|
18
19
|
|
|
19
20
|
export function buildCopyEditBatchPrompt(batch, { cwd = process.cwd() } = {}) {
|
|
20
|
-
const
|
|
21
|
+
const compactBatch = compactBatchForPrompt(batch);
|
|
22
|
+
const repairLines = compactBatch.repair ? [
|
|
21
23
|
'',
|
|
22
24
|
'Repair mode:',
|
|
23
25
|
'- The previous Apply attempt changed source, but validation failed.',
|
|
@@ -28,7 +30,7 @@ export function buildCopyEditBatchPrompt(batch, { cwd = process.cwd() } = {}) {
|
|
|
28
30
|
'- If failures or candidates show edited text is also a lookup key, update coupled count, animation, icon, image, asset, style, or metadata keys in the current source, or fail that entry without partial edits.',
|
|
29
31
|
'- Keep failed and notes as arrays.',
|
|
30
32
|
'- Return the same canonical JSON shape after repair.',
|
|
31
|
-
JSON.stringify(
|
|
33
|
+
JSON.stringify(compactBatch.repair, null, 2),
|
|
32
34
|
] : [];
|
|
33
35
|
return [
|
|
34
36
|
'You are the Impeccable staged copy-edit batch applier.',
|
|
@@ -80,7 +82,7 @@ export function buildCopyEditBatchPrompt(batch, { cwd = process.cwd() } = {}) {
|
|
|
80
82
|
...repairLines,
|
|
81
83
|
'',
|
|
82
84
|
'Staged copy-edit batch:',
|
|
83
|
-
JSON.stringify(
|
|
85
|
+
JSON.stringify(compactBatch, null, 2),
|
|
84
86
|
].join('\n');
|
|
85
87
|
}
|
|
86
88
|
|
|
@@ -292,7 +294,7 @@ function readManualEditValidationScript(cwd) {
|
|
|
292
294
|
function compactBatchForPrompt(batch) {
|
|
293
295
|
return {
|
|
294
296
|
pageUrl: batch?.pageUrl || null,
|
|
295
|
-
repair: batch?.repair
|
|
297
|
+
repair: compactBatchRepair(batch?.repair),
|
|
296
298
|
entries: (batch?.entries || []).map((entry) => ({
|
|
297
299
|
id: entry.id,
|
|
298
300
|
pageUrl: entry.pageUrl,
|
|
@@ -300,7 +302,71 @@ function compactBatchForPrompt(batch) {
|
|
|
300
302
|
element: compactContextForBatch(entry.element),
|
|
301
303
|
ops: (entry.ops || []).map(compactBatchOp),
|
|
302
304
|
})),
|
|
303
|
-
candidates: batch?.candidates
|
|
305
|
+
candidates: compactBatchCandidates(batch?.candidates),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function compactBatchRepair(repair) {
|
|
310
|
+
if (!repair || typeof repair !== 'object') return undefined;
|
|
311
|
+
return {
|
|
312
|
+
status: compactBatchString(repair.status),
|
|
313
|
+
attempt: normalizeOptionalBatchNumber(repair.attempt),
|
|
314
|
+
attempts: normalizeOptionalBatchNumber(repair.attempts),
|
|
315
|
+
maxAttempts: normalizeOptionalBatchNumber(repair.maxAttempts),
|
|
316
|
+
reason: compactBatchString(repair.reason),
|
|
317
|
+
transactionId: compactBatchString(repair.transactionId),
|
|
318
|
+
pageUrl: compactBatchString(repair.pageUrl),
|
|
319
|
+
failures: compactBatchDiagnostics(repair.failures),
|
|
320
|
+
files: compactBatchStringList(repair.files, 20),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function compactBatchDiagnostics(items, depth = 0) {
|
|
325
|
+
if (!Array.isArray(items)) return undefined;
|
|
326
|
+
return items.slice(0, 12).map((item) => ({
|
|
327
|
+
entryId: compactBatchString(item?.entryId || item?.id),
|
|
328
|
+
reason: compactBatchString(item?.reason || item?.kind),
|
|
329
|
+
detail: compactBatchString(item?.detail),
|
|
330
|
+
message: compactBatchString(item?.message),
|
|
331
|
+
file: compactBatchString(item?.file || item?.relativeFile),
|
|
332
|
+
line: normalizeOptionalBatchNumber(item?.line),
|
|
333
|
+
ref: compactBatchString(item?.ref),
|
|
334
|
+
marker: compactBatchString(item?.marker),
|
|
335
|
+
files: compactBatchStringList(item?.files, 8),
|
|
336
|
+
candidates: depth < 2 ? compactBatchSourceMatches(item?.candidates, 8) : undefined,
|
|
337
|
+
failures: depth < 2 ? compactBatchDiagnostics(item?.failures, depth + 1) : undefined,
|
|
338
|
+
checks: depth < 2 ? compactBatchDiagnostics(item?.checks, depth + 1) : undefined,
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function compactBatchCandidates(candidates) {
|
|
343
|
+
return (Array.isArray(candidates) ? candidates : [])
|
|
344
|
+
.slice(0, 24)
|
|
345
|
+
.map((candidate) => ({
|
|
346
|
+
entryId: compactBatchString(candidate?.entryId),
|
|
347
|
+
ref: compactBatchString(candidate?.ref),
|
|
348
|
+
sourceHint: compactBatchSourceMatch(candidate?.sourceHint),
|
|
349
|
+
textMatches: compactBatchSourceMatches(candidate?.textMatches, 8),
|
|
350
|
+
objectKeyMatches: compactBatchSourceMatches(candidate?.objectKeyMatches, 8),
|
|
351
|
+
contextTextMatches: compactBatchSourceMatches(candidate?.contextTextMatches, 8),
|
|
352
|
+
locatorMatches: compactBatchSourceMatches(candidate?.locatorMatches, 6),
|
|
353
|
+
}));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function compactBatchSourceMatches(matches, limit) {
|
|
357
|
+
if (!Array.isArray(matches)) return undefined;
|
|
358
|
+
return matches.slice(0, limit).map(compactBatchSourceMatch).filter(Boolean);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function compactBatchSourceMatch(match) {
|
|
362
|
+
if (!match || typeof match !== 'object') return null;
|
|
363
|
+
return {
|
|
364
|
+
file: compactBatchString(match.relativeFile || match.file),
|
|
365
|
+
line: normalizeBatchNumber(match.line),
|
|
366
|
+
column: normalizeBatchNumber(match.column),
|
|
367
|
+
kind: compactBatchString(match.kind),
|
|
368
|
+
reason: compactBatchString(match.reason || match.kind),
|
|
369
|
+
status: compactBatchString(match.status),
|
|
304
370
|
};
|
|
305
371
|
}
|
|
306
372
|
|
|
@@ -311,25 +377,77 @@ function compactBatchOp(op) {
|
|
|
311
377
|
contextRef: op.contextRef,
|
|
312
378
|
tag: op.tag,
|
|
313
379
|
elementId: op.elementId,
|
|
314
|
-
classes: op.classes,
|
|
380
|
+
classes: compactBatchStringList(op.classes, 24),
|
|
315
381
|
originalText: op.originalText,
|
|
316
382
|
newText: op.newText,
|
|
317
383
|
deleted: op.deleted === true || undefined,
|
|
318
|
-
sourceHint: op.sourceHint,
|
|
384
|
+
sourceHint: normalizeBatchSourceHint(op.sourceHint),
|
|
319
385
|
leaf: compactContextForBatch(op.leaf),
|
|
320
|
-
nearbyEditableTexts:
|
|
386
|
+
nearbyEditableTexts: compactNearbyBatchTexts(op.nearbyEditableTexts),
|
|
321
387
|
container: compactContextForBatch(op.container),
|
|
322
|
-
contextHints:
|
|
388
|
+
contextHints: compactBatchStringList(op.contextHints, 12),
|
|
323
389
|
};
|
|
324
390
|
}
|
|
325
391
|
|
|
392
|
+
function normalizeBatchSourceHint(hint) {
|
|
393
|
+
if (!hint || typeof hint !== 'object') return null;
|
|
394
|
+
let line = normalizeBatchNumber(hint.line);
|
|
395
|
+
let column = normalizeBatchNumber(hint.column);
|
|
396
|
+
if ((line === null || column === null) && typeof hint.loc === 'string') {
|
|
397
|
+
const match = hint.loc.match(/^(\d+)(?::(\d+))?/);
|
|
398
|
+
if (match) {
|
|
399
|
+
line = Number(match[1]);
|
|
400
|
+
if (match[2]) column = Number(match[2]);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
file: compactBatchString(hint.file) || '',
|
|
405
|
+
loc: compactBatchString(hint.loc) || '',
|
|
406
|
+
line,
|
|
407
|
+
column,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function normalizeBatchNumber(value) {
|
|
412
|
+
if (value === null || value === undefined || value === '') return null;
|
|
413
|
+
const number = Number(value);
|
|
414
|
+
return Number.isFinite(number) ? number : null;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function normalizeOptionalBatchNumber(value) {
|
|
418
|
+
const number = normalizeBatchNumber(value);
|
|
419
|
+
return number === null ? undefined : number;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function compactNearbyBatchTexts(items) {
|
|
423
|
+
return (Array.isArray(items) ? items : [])
|
|
424
|
+
.slice(0, 8)
|
|
425
|
+
.map((item) => typeof item === 'string' ? { text: truncate(item, BATCH_OP_TEXT_LIMIT) } : {
|
|
426
|
+
ref: compactBatchString(item?.ref),
|
|
427
|
+
tag: compactBatchString(item?.tag),
|
|
428
|
+
classes: compactBatchStringList(item?.classes, 24),
|
|
429
|
+
text: compactBatchString(item?.text),
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function compactBatchStringList(items, limit) {
|
|
434
|
+
return (Array.isArray(items) ? items : [])
|
|
435
|
+
.slice(0, limit)
|
|
436
|
+
.filter((item) => typeof item === 'string')
|
|
437
|
+
.map((item) => truncate(item, BATCH_OP_TEXT_LIMIT));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function compactBatchString(value) {
|
|
441
|
+
return typeof value === 'string' ? truncate(value, BATCH_OP_TEXT_LIMIT) : undefined;
|
|
442
|
+
}
|
|
443
|
+
|
|
326
444
|
function compactContextForBatch(value) {
|
|
327
445
|
if (!value || typeof value !== 'object') return value || null;
|
|
328
446
|
return {
|
|
329
|
-
ref: value.ref,
|
|
330
|
-
tagName: value.tagName,
|
|
331
|
-
id: value.id,
|
|
332
|
-
classes: value.classes,
|
|
447
|
+
ref: compactBatchString(value.ref),
|
|
448
|
+
tagName: compactBatchString(value.tagName),
|
|
449
|
+
id: compactBatchString(value.id),
|
|
450
|
+
classes: compactBatchStringList(value.classes, 24),
|
|
333
451
|
textContent: truncate(value.textContent, 900),
|
|
334
452
|
outerHTML: truncate(stripLiveRuntimeHtml(value.outerHTML), 1800),
|
|
335
453
|
};
|
|
@@ -470,12 +588,11 @@ function runClaude(prompt, { cwd, env, resultPath, logPath, timeoutMs = DEFAULT_
|
|
|
470
588
|
if (env.IMPECCABLE_LIVE_COPY_AGENT_MODEL) {
|
|
471
589
|
args.push('--model', env.IMPECCABLE_LIVE_COPY_AGENT_MODEL);
|
|
472
590
|
}
|
|
473
|
-
args.push(prompt);
|
|
474
591
|
// Forward env as-is so CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY flow
|
|
475
592
|
// through. On macOS, `claude /login` stores creds in the Keychain, which a
|
|
476
593
|
// non-TTY subprocess cannot read; setting CLAUDE_CODE_OAUTH_TOKEN (via
|
|
477
594
|
// `claude setup-token`) is the supported headless auth path.
|
|
478
|
-
return runAgentProcess('claude', args,
|
|
595
|
+
return runAgentProcess('claude', args, prompt, { cwd, env, logPath, timeoutMs, mirrorOutputPath: resultPath });
|
|
479
596
|
}
|
|
480
597
|
|
|
481
598
|
function runAgentProcess(command, args, stdin, { cwd, env, logPath, timeoutMs, mirrorOutputPath }) {
|
|
@@ -27,6 +27,7 @@ import fs from 'node:fs';
|
|
|
27
27
|
import path from 'node:path';
|
|
28
28
|
import { fileURLToPath } from 'node:url';
|
|
29
29
|
import { resolveLiveConfigPath } from './lib/impeccable-paths.mjs';
|
|
30
|
+
import { livePathGlobToRegex } from './lib/live-path-globs.mjs';
|
|
30
31
|
import {
|
|
31
32
|
describeInjectArtifacts,
|
|
32
33
|
frameworkIgnorePatterns,
|
|
@@ -364,7 +365,7 @@ export function resolveFiles(rootDir, config) {
|
|
|
364
365
|
const patterns = config.files;
|
|
365
366
|
const userExcludes = Array.isArray(config.exclude) ? config.exclude : [];
|
|
366
367
|
const allExcludes = [...HARD_EXCLUDES, ...userExcludes];
|
|
367
|
-
const excludeRegexes = allExcludes.map(
|
|
368
|
+
const excludeRegexes = allExcludes.map(livePathGlobToRegex);
|
|
368
369
|
|
|
369
370
|
const isExcluded = (relPath) => excludeRegexes.some((re) => re.test(relPath));
|
|
370
371
|
const isGlob = (s) => /[*?[]/.test(s);
|
|
@@ -401,47 +402,6 @@ export function resolveFiles(rootDir, config) {
|
|
|
401
402
|
return out;
|
|
402
403
|
}
|
|
403
404
|
|
|
404
|
-
/**
|
|
405
|
-
* Convert a glob pattern to a RegExp. Supports:
|
|
406
|
-
* ** → any number of path segments (including zero)
|
|
407
|
-
* * → any chars except `/`
|
|
408
|
-
* ? → any single char except `/`
|
|
409
|
-
* Paths are normalized to forward slashes before matching.
|
|
410
|
-
*/
|
|
411
|
-
function globToRegex(pattern) {
|
|
412
|
-
let re = '';
|
|
413
|
-
let i = 0;
|
|
414
|
-
while (i < pattern.length) {
|
|
415
|
-
const c = pattern[i];
|
|
416
|
-
if (c === '*') {
|
|
417
|
-
if (pattern[i + 1] === '*') {
|
|
418
|
-
// ** — any number of segments, including zero. Handle the common
|
|
419
|
-
// **/ and /** forms so `a/**/b` matches `a/b` as well as `a/x/y/b`.
|
|
420
|
-
if (pattern[i + 2] === '/') {
|
|
421
|
-
re += '(?:.*/)?';
|
|
422
|
-
i += 3;
|
|
423
|
-
} else {
|
|
424
|
-
re += '.*';
|
|
425
|
-
i += 2;
|
|
426
|
-
}
|
|
427
|
-
} else {
|
|
428
|
-
re += '[^/]*';
|
|
429
|
-
i += 1;
|
|
430
|
-
}
|
|
431
|
-
} else if (c === '?') {
|
|
432
|
-
re += '[^/]';
|
|
433
|
-
i += 1;
|
|
434
|
-
} else if (/[.+^${}()|[\]\\]/.test(c)) {
|
|
435
|
-
re += '\\' + c;
|
|
436
|
-
i += 1;
|
|
437
|
-
} else {
|
|
438
|
-
re += c;
|
|
439
|
-
i += 1;
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
return new RegExp('^' + re + '$');
|
|
443
|
-
}
|
|
444
|
-
|
|
445
405
|
// ---------------------------------------------------------------------------
|
|
446
406
|
// Core operations
|
|
447
407
|
// ---------------------------------------------------------------------------
|
|
@@ -238,10 +238,9 @@ export async function completeAcceptHandling(event, base, token) {
|
|
|
238
238
|
});
|
|
239
239
|
} catch (err) {
|
|
240
240
|
event._completionAck = { ok: false, error: err.message };
|
|
241
|
+
return event;
|
|
241
242
|
}
|
|
242
|
-
|
|
243
|
-
event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
|
|
244
|
-
}
|
|
243
|
+
event._completionAck = completionAckForAcceptResult(event.id, completionType, event._acceptResult);
|
|
245
244
|
return event;
|
|
246
245
|
}
|
|
247
246
|
|
|
@@ -269,9 +268,11 @@ export function printPollEvent(event) {
|
|
|
269
268
|
// Situational plumbing rides with the event itself: `_instructions` is the
|
|
270
269
|
// authoritative next step, with real ids and paths substituted, so the
|
|
271
270
|
// reference doc can stay lean and can never drift from script behavior.
|
|
272
|
-
|
|
271
|
+
// A wire-supplied value must never win over the locally generated one.
|
|
272
|
+
if (event && typeof event === 'object') {
|
|
273
273
|
const instructions = instructionsForEvent(event, { scriptsPath: SELF_DIR });
|
|
274
274
|
if (instructions) event._instructions = instructions;
|
|
275
|
+
else delete event._instructions;
|
|
275
276
|
}
|
|
276
277
|
console.log(JSON.stringify(event));
|
|
277
278
|
}
|