@haystackeditor/cli 0.15.28 → 0.15.30

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.
@@ -2,8 +2,9 @@
2
2
  * Dependency-free browser half of Haystack's experimental web/Node behavior
3
3
  * atlas. A build transform supplies an exact manifest; this runtime records
4
4
  * only manifest-approved enumerated outcomes and propagates a random trace ID
5
- * to same-origin requests. It never reads DOM text, request bodies, headers,
6
- * cookies, storage values, or arbitrary object properties.
5
+ * to same-origin requests. It never reads DOM text, request bodies, header
6
+ * values beyond fixed protocol classification, cookies, storage values, or
7
+ * arbitrary object properties.
7
8
  */
8
9
  var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
9
10
  'use strict';
@@ -65,6 +66,10 @@ var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
65
66
  var nativeSetTimeout = nativeLooking(hostSetTimeout) ? function () {
66
67
  return nativeReflectApply(hostSetTimeout, host, arguments);
67
68
  } : null;
69
+ var hostClearTimeout = safeHostData('clearTimeout');
70
+ var nativeClearTimeout = nativeLooking(hostClearTimeout) ? function () {
71
+ return nativeReflectApply(hostClearTimeout, host, arguments);
72
+ } : null;
68
73
  var hostPromise = safeHostData('Promise');
69
74
  var promisePrototype = nativeLooking(hostPromise) ? safeNativeMember(hostPromise, 'prototype') : null;
70
75
  var promiseThen = promisePrototype ? safeNativeMember(promisePrototype, 'then') : null;
@@ -868,7 +873,7 @@ var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
868
873
  return result;
869
874
  }
870
875
 
871
- function axiosAt(token, owner, callable, receiver, configIndex, safeConfig, applicationArguments) {
876
+ function axiosAt(token, owner, callable, receiver, ownerProperty, configIndex, safeConfig, applicationArguments) {
872
877
  if (!nativeArrayIsArray(applicationArguments) || typeof callable !== 'function') {
873
878
  return nativeReflectApply(callable, receiver, applicationArguments);
874
879
  }
@@ -877,7 +882,10 @@ var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
877
882
  if (context && !admitProbe(context)) return nativeReflectApply(callable, receiver, applicationArguments);
878
883
  var sites = context && context.runtimeConfig && context.runtimeConfig.fetchSites[token];
879
884
  if (!context || !sites) return nativeReflectApply(callable, receiver, applicationArguments);
880
- if (safeConfig !== true || !Number.isInteger(configIndex) || configIndex < 0 || configIndex > 8 ||
885
+ if ((ownerProperty !== null && (typeof ownerProperty !== 'string' || ownerProperty.length === 0 ||
886
+ ownerProperty.length > 256 || ownerProperty === '__proto__' || ownerProperty === 'constructor' ||
887
+ ownerProperty === 'prototype')) || safeConfig !== true || !Number.isInteger(configIndex) ||
888
+ configIndex < 0 || configIndex > 8 ||
881
889
  !platformFetchCorrelationAllowed()) {
882
890
  omit(context);
883
891
  return nativeReflectApply(callable, receiver, applicationArguments);
@@ -886,6 +894,20 @@ var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
886
894
  var args = [];
887
895
  var config;
888
896
  try {
897
+ if (ownerProperty !== null) {
898
+ if ((typeof receiver !== 'object' || receiver === null) && typeof receiver !== 'function') {
899
+ axiosOmission(state);
900
+ return nativeReflectApply(callable, receiver, applicationArguments);
901
+ }
902
+ var ownerDescriptor = nativeGetOwnPropertyDescriptor(receiver, ownerProperty);
903
+ if (!ownerDescriptor || !nativeReflectApply(nativeHasOwnProperty, ownerDescriptor, ['value']) ||
904
+ ((typeof ownerDescriptor.value !== 'object' || ownerDescriptor.value === null) &&
905
+ typeof ownerDescriptor.value !== 'function')) {
906
+ axiosOmission(state);
907
+ return nativeReflectApply(callable, receiver, applicationArguments);
908
+ }
909
+ owner = ownerDescriptor.value;
910
+ }
889
911
  for (var argumentIndex = 0; argumentIndex < applicationArguments.length; argumentIndex++) {
890
912
  args[argumentIndex] = applicationArguments[argumentIndex];
891
913
  }
@@ -1028,6 +1050,146 @@ var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
1028
1050
  return correlatedFetch(fetchImplementation, input, init, sites, hasInit);
1029
1051
  }
1030
1052
 
1053
+ function nextServerActionAt(token, callable, args) {
1054
+ var context = active;
1055
+ if (!context || context.saturated || !admitProbe(context)) {
1056
+ return nativeReflectApply(callable, undefined, args);
1057
+ }
1058
+ var sites = context.runtimeConfig && context.runtimeConfig.fetchSites[token];
1059
+ if (!sites || !nativeFetchFunction || typeof nativeDefineProperty !== 'function' ||
1060
+ !nativeSetTimeout || !nativeClearTimeout) {
1061
+ omit(context);
1062
+ return nativeReflectApply(callable, undefined, args);
1063
+ }
1064
+ var originalDescriptor;
1065
+ try {
1066
+ originalDescriptor = nativeGetOwnPropertyDescriptor(host, 'fetch');
1067
+ } catch (_) {
1068
+ omit(context);
1069
+ return nativeReflectApply(callable, undefined, args);
1070
+ }
1071
+ if (!originalDescriptor || originalDescriptor.configurable !== true ||
1072
+ !nativeReflectApply(nativeHasOwnProperty, originalDescriptor, ['value']) ||
1073
+ originalDescriptor.value !== nativeFetchFunction) {
1074
+ omit(context);
1075
+ return nativeReflectApply(callable, undefined, args);
1076
+ }
1077
+ var observed = false;
1078
+ var restored = false;
1079
+ var omissionRecorded = false;
1080
+ var restoreTimer = null;
1081
+ var recordMissing = function () {
1082
+ if (observed || omissionRecorded) return;
1083
+ omissionRecorded = true;
1084
+ omit(context);
1085
+ };
1086
+ var restore = function () {
1087
+ if (restored) return;
1088
+ restored = true;
1089
+ if (restoreTimer !== null && nativeClearTimeout) {
1090
+ try { nativeClearTimeout(restoreTimer); } catch (_) { failOpen(); }
1091
+ }
1092
+ try {
1093
+ var currentDescriptor = nativeGetOwnPropertyDescriptor(host, 'fetch');
1094
+ if (currentDescriptor && currentDescriptor.configurable === originalDescriptor.configurable &&
1095
+ currentDescriptor.enumerable === originalDescriptor.enumerable &&
1096
+ currentDescriptor.writable === originalDescriptor.writable &&
1097
+ currentDescriptor.value === scopedFetch) {
1098
+ nativeDefineProperty(host, 'fetch', originalDescriptor);
1099
+ } else {
1100
+ // Application/framework mutation wins; never overwrite an owner we
1101
+ // cannot identify exactly.
1102
+ omit(context);
1103
+ }
1104
+ } catch (_) {
1105
+ omit(context);
1106
+ failOpen();
1107
+ }
1108
+ };
1109
+ var exactNextActionInit = function (init) {
1110
+ try {
1111
+ if (!init || typeof init !== 'object' || nativeGetPrototypeOf(init) !== nativeObjectPrototype ||
1112
+ typeof nativeGetOwnPropertyDescriptors !== 'function') return false;
1113
+ var descriptors = nativeGetOwnPropertyDescriptors(init);
1114
+ if (!descriptors.method || descriptors.method.value !== 'POST' || !descriptors.headers ||
1115
+ !nativeReflectApply(nativeHasOwnProperty, descriptors.headers, ['value'])) return false;
1116
+ var headers = descriptors.headers.value;
1117
+ if (!headers || typeof headers !== 'object' || nativeGetPrototypeOf(headers) !== nativeObjectPrototype) return false;
1118
+ var keys = nativeObjectKeys(headers);
1119
+ if (keys.length > 32) return false;
1120
+ var actionHeader = false;
1121
+ var rscAccept = false;
1122
+ for (var index = 0; index < keys.length; index++) {
1123
+ var descriptor = nativeGetOwnPropertyDescriptor(headers, keys[index]);
1124
+ if (!descriptor || !nativeReflectApply(nativeHasOwnProperty, descriptor, ['value']) ||
1125
+ typeof descriptor.value !== 'string') return false;
1126
+ var normalized = keys[index].toLowerCase();
1127
+ if (normalized === 'next-action') actionHeader = descriptor.value.length > 0;
1128
+ if (normalized === 'accept') rscAccept = descriptor.value.toLowerCase().indexOf('text/x-component') !== -1;
1129
+ }
1130
+ return actionHeader && rscAccept;
1131
+ } catch (_) {
1132
+ return false;
1133
+ }
1134
+ };
1135
+ var scopedFetch = function haystackNextServerActionFetch(input, init) {
1136
+ if (context !== active || observed || arguments.length !== 2 || !exactNextActionInit(init)) {
1137
+ return nativeReflectApply(nativeFetchFunction, host, arguments);
1138
+ }
1139
+ observed = true;
1140
+ restore();
1141
+ return correlatedFetch(nativeFetchFunction, input, init, sites, arguments.length >= 2);
1142
+ };
1143
+ try {
1144
+ nativeDefineProperty(host, 'fetch', {
1145
+ configurable: originalDescriptor.configurable,
1146
+ enumerable: originalDescriptor.enumerable,
1147
+ writable: originalDescriptor.writable,
1148
+ value: scopedFetch,
1149
+ });
1150
+ } catch (_) {
1151
+ omit(context);
1152
+ return nativeReflectApply(callable, undefined, args);
1153
+ }
1154
+ try {
1155
+ restoreTimer = nativeSetTimeout(function () {
1156
+ restore();
1157
+ recordMissing();
1158
+ }, 1000);
1159
+ } catch (_) {
1160
+ restore();
1161
+ recordMissing();
1162
+ return nativeReflectApply(callable, undefined, args);
1163
+ }
1164
+ var result;
1165
+ try {
1166
+ result = nativeReflectApply(callable, undefined, args);
1167
+ } catch (error) {
1168
+ restore();
1169
+ recordMissing();
1170
+ throw error;
1171
+ }
1172
+ if (nativePromiseThen && result !== null &&
1173
+ (typeof result === 'object' || typeof result === 'function')) {
1174
+ try {
1175
+ nativeReflectApply(nativePromiseThen, result, [function () {
1176
+ restore();
1177
+ recordMissing();
1178
+ }, function () {
1179
+ restore();
1180
+ recordMissing();
1181
+ }]);
1182
+ } catch (_) {
1183
+ restore();
1184
+ recordMissing();
1185
+ }
1186
+ } else {
1187
+ restore();
1188
+ recordMissing();
1189
+ }
1190
+ return result;
1191
+ }
1192
+
1031
1193
  function mergeAngularHttpContractOptions(options, headerPairs) {
1032
1194
  try {
1033
1195
  if (!options || typeof options !== 'object' || nativeGetPrototypeOf(options) !== nativeObjectPrototype ||
@@ -1430,6 +1592,7 @@ var __haystackWebAtlasModuleApi = (function installHaystackWebAtlas(host) {
1430
1592
  condition: function (siteId, outcome) { if (admitProbe(active)) emit(siteId, 'condition', outcome); },
1431
1593
  fetch: correlatedFetch,
1432
1594
  fetchAt: fetchAt,
1595
+ nextServerActionAt: nextServerActionAt,
1433
1596
  angularHttpAt: angularHttpAt,
1434
1597
  axiosAt: axiosAt,
1435
1598
  oazapftsAt: oazapftsAt,
@@ -0,0 +1,68 @@
1
+ import type { FrontHalfEnqueueRequest, RepoWalkHookStatus } from './verify-precompute.js';
2
+ /** FIXED CONTRACT: hook delivery captures the exact request before returning.
3
+ * Persist request and pending receipt with private permissions and durable,
4
+ * atomic publication before starting a detached sender. Do not persist tokens.
5
+ * The sender reads this immutable request, never reconstructs newer source,
6
+ * and performs one authenticated POST with a total 60-second bound. Pending
7
+ * is local custody only; acknowledged requires the existing validated server
8
+ * response. Each delivery owns its receipt so older senders cannot overwrite
9
+ * newer status. A latest-delivery pointer is written only by hook submission.
10
+ * Failures/timeouts remain inspectable and cannot imply remote acceptance.
11
+ * Terminal receipts retain exact request identity; after receipt fsync, remove
12
+ * the captured patch file. Keep at most 50 terminal delivery directories on
13
+ * later submissions, excluding the latest pointer and pending deliveries.
14
+ * Explicit non-hook invocation retains its current synchronous behavior.
15
+ * No new model/browser work, retry loop, or shared cache identity is added.
16
+ * On Windows, owner-only access uses a protected current-user SID ACL,
17
+ * established before capture and checked by the sender, not POSIX mode bits.
18
+ * File contents are flushed before rename on every platform. Directory fsync
19
+ * is POSIX-only; Windows publication does not promise power-loss durability.
20
+ * Windows requests remain logically immutable without the read-only attribute,
21
+ * so terminal cleanup can remove them. ACL setup/read failure fails closed.
22
+ * A safe regular captured file may be parsed and identity-validated locally
23
+ * before its privacy check. A rejected privacy check carries that identity
24
+ * only for recording a failed receipt, never for a POST. Both this failure
25
+ * path and the normal sender must acquire the same exclusive sender marker
26
+ * before changing a receipt or deleting the capture. Unsafe/corrupt paths or
27
+ * an unwritable store cannot authorize a fallback mutation.
28
+ */
29
+ export interface PrecomputeDeliveryRequest {
30
+ schemaVersion: 'precompute-delivery-v1';
31
+ deliveryId: string;
32
+ request: FrontHalfEnqueueRequest;
33
+ }
34
+ export interface PrecomputeDeliveryAccessFailure extends Error {
35
+ readonly delivery: PrecomputeDeliveryRequest;
36
+ }
37
+ export type PrecomputeAcknowledgment = {
38
+ outcome: 'enqueued' | 'cached' | 'existing';
39
+ runId?: string;
40
+ walker?: RepoWalkHookStatus;
41
+ };
42
+ export type PrecomputeDeliveryReceipt = {
43
+ schemaVersion: 'precompute-delivery-receipt-v1';
44
+ deliveryId: string;
45
+ repository: string;
46
+ sourceCommit: string;
47
+ updatedAt: string;
48
+ requestIdentity: Pick<FrontHalfEnqueueRequest, 'baseCommit' | 'workCommit' | 'observedAt' | 'cacheKey' | 'patchSha256'>;
49
+ } & ({
50
+ status: 'pending';
51
+ } | {
52
+ status: 'acknowledged';
53
+ acknowledgment: PrecomputeAcknowledgment;
54
+ } | {
55
+ status: 'failed' | 'timed-out';
56
+ reason: string;
57
+ });
58
+ export interface PrecomputeDeliveryPointer {
59
+ schemaVersion: 'precompute-delivery-pointer-v1';
60
+ deliveryId: string;
61
+ repository: string;
62
+ sourceCommit: string;
63
+ }
64
+ export type StartPrecomputeDelivery = (metadataDirectory: string, request: FrontHalfEnqueueRequest) => Promise<{
65
+ deliveryId: string;
66
+ requestPath: string;
67
+ }>;
68
+ export type DeliverPrecomputeRequest = (request: FrontHalfEnqueueRequest, signal: AbortSignal) => Promise<PrecomputeAcknowledgment>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ import { NotLoggedInError } from '../utils/auth.js';
2
+ import { HaystackApiError } from '../utils/haystack-api.js';
3
+ import { deliverPrecomputeRequest } from './verify-precompute.js';
4
+ import { claimPrecomputeDelivery, PrecomputeDeliveryAccessError, readPrecomputeDelivery, writePrecomputeDeliveryReceipt } from './precompute-delivery.js';
5
+ // Standalone compiled entry point. Its only argument is a captured request path.
6
+ // Tokens are resolved in memory from the inherited auth environment/files.
7
+ const controller = new AbortController();
8
+ const requestPath = process.argv.length === 3 ? process.argv[2] : null;
9
+ let delivery = null;
10
+ let finished = false;
11
+ function finish(result) {
12
+ finished = true;
13
+ clearTimeout(deadline);
14
+ try {
15
+ if (requestPath && delivery)
16
+ writePrecomputeDeliveryReceipt(requestPath, delivery, result);
17
+ process.exit(0);
18
+ }
19
+ catch {
20
+ process.exit(1);
21
+ }
22
+ }
23
+ function terminal(status, reason) {
24
+ if (!delivery)
25
+ process.exit(1);
26
+ return finish({ status, reason });
27
+ }
28
+ const deadline = setTimeout(() => {
29
+ controller.abort();
30
+ if (!finished)
31
+ terminal('timed-out', 'delivery-deadline-exceeded; remote-acceptance-unknown');
32
+ }, 60_000);
33
+ try {
34
+ if (!requestPath)
35
+ throw new Error('Missing captured request.');
36
+ let accessRejected = false;
37
+ try {
38
+ delivery = readPrecomputeDelivery(requestPath);
39
+ }
40
+ catch (error) {
41
+ if (!(error instanceof PrecomputeDeliveryAccessError))
42
+ throw error;
43
+ delivery = error.delivery;
44
+ accessRejected = true;
45
+ }
46
+ // A duplicate sender must not replace the first sender's receipt.
47
+ try {
48
+ claimPrecomputeDelivery(requestPath);
49
+ }
50
+ catch {
51
+ process.exit(1);
52
+ }
53
+ if (accessRejected)
54
+ terminal('failed', 'captured-request-access-rejected');
55
+ const acknowledgment = await deliverPrecomputeRequest(delivery.request, controller.signal);
56
+ finish({ status: 'acknowledged', acknowledgment });
57
+ }
58
+ catch (error) {
59
+ if (finished)
60
+ process.exit(0);
61
+ if (controller.signal.aborted)
62
+ terminal('timed-out', 'delivery-deadline-exceeded; remote-acceptance-unknown');
63
+ if (error instanceof NotLoggedInError)
64
+ terminal('failed', 'authentication-required');
65
+ if (error instanceof HaystackApiError)
66
+ terminal('failed', `server-http-${error.status}`);
67
+ terminal('failed', 'delivery-not-acknowledged; remote-acceptance-unknown');
68
+ }
@@ -0,0 +1,20 @@
1
+ import type { PrecomputeDeliveryAccessFailure, PrecomputeDeliveryReceipt, PrecomputeDeliveryRequest, StartPrecomputeDelivery } from './precompute-delivery-contract.js';
2
+ export declare class PrecomputeDeliveryAccessError extends Error implements PrecomputeDeliveryAccessFailure {
3
+ readonly delivery: PrecomputeDeliveryRequest;
4
+ constructor(delivery: PrecomputeDeliveryRequest);
5
+ }
6
+ export declare function readPrecomputeDelivery(requestPath: string): PrecomputeDeliveryRequest;
7
+ export declare function writePrecomputeDeliveryReceipt(requestPath: string, delivery: PrecomputeDeliveryRequest, result: {
8
+ status: 'pending';
9
+ } | {
10
+ status: 'acknowledged';
11
+ acknowledgment: Extract<PrecomputeDeliveryReceipt, {
12
+ status: 'acknowledged';
13
+ }>['acknowledgment'];
14
+ } | {
15
+ status: 'failed' | 'timed-out';
16
+ reason: string;
17
+ }): void;
18
+ /** An exclusive durable marker prevents a second invocation from posting this delivery. */
19
+ export declare function claimPrecomputeDelivery(requestPath: string): void;
20
+ export declare const startPrecomputeDelivery: StartPrecomputeDelivery;