@outerlayer/cli 0.2.0 → 0.4.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.
Files changed (141) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +229 -60
  3. package/dist/agent-setup-IFH3FB5X.js +197 -0
  4. package/dist/build-TZUUTRGH.js +9 -0
  5. package/dist/build-info.json +1 -1
  6. package/dist/check-7MFH6HNC.js +94 -0
  7. package/dist/chunk-3TFPDVTI.js +94 -0
  8. package/dist/{chunk-4TNZMO7V.js → chunk-4C4THABW.js} +5566 -754
  9. package/dist/{chunk-R5KBGVII.js → chunk-5QRP3MVS.js} +30 -14
  10. package/dist/chunk-5Y3QQRUH.js +300 -0
  11. package/dist/chunk-774HEQL6.js +178 -0
  12. package/dist/{work-pr-cmd-AZQPWH4H.js → chunk-7WERLFVR.js} +9 -26
  13. package/dist/chunk-ABIWDUMS.js +104 -0
  14. package/dist/chunk-AUFG23AA.js +534 -0
  15. package/dist/chunk-B2G7JHHB.js +42 -0
  16. package/dist/chunk-BCJNHMZT.js +34 -0
  17. package/dist/chunk-BCLJSQCV.js +56 -0
  18. package/dist/chunk-BFESLKPP.js +61 -0
  19. package/dist/chunk-BJ3KTMDH.js +63 -0
  20. package/dist/chunk-BKO6JEZI.js +47 -0
  21. package/dist/chunk-BOLTI6LR.js +37 -0
  22. package/dist/chunk-CBPPJSAR.js +89 -0
  23. package/dist/chunk-DM3VFDS3.js +1461 -0
  24. package/dist/{chunk-65WXAANR.js → chunk-DVDEBNQJ.js} +17 -2
  25. package/dist/{chunk-TFUIDMOB.js → chunk-EABW6AJQ.js} +12 -1
  26. package/dist/{chunk-KFYJV2ZG.js → chunk-EMY4I27X.js} +1 -1
  27. package/dist/{chunk-NTTPJV35.js → chunk-F47JBIAW.js} +3 -1
  28. package/dist/chunk-F6GFZXZ3.js +60 -0
  29. package/dist/{chunk-YOOSBOKS.js → chunk-F7CU5ABH.js} +1 -1
  30. package/dist/{emit-cmd-TWSYYEZI.js → chunk-H5NCNVDA.js} +68 -17
  31. package/dist/chunk-HZRNMGLF.js +2233 -0
  32. package/dist/chunk-LF6MLJCY.js +38 -0
  33. package/dist/{chunk-U32VSRLO.js → chunk-LT5TZHYH.js} +95 -634
  34. package/dist/chunk-LYCDNMOH.js +83 -0
  35. package/dist/chunk-M5POMKKW.js +1051 -0
  36. package/dist/{mcp-install-cmd-FDQH6SEN.js → chunk-MQ3IPHIZ.js} +35 -18
  37. package/dist/{chunk-D77LS3UI.js → chunk-N5FOE5PS.js} +33 -4
  38. package/dist/chunk-N6LURUEF.js +64 -0
  39. package/dist/chunk-OGFGZQA3.js +23 -0
  40. package/dist/chunk-QDQEUVUF.js +9 -0
  41. package/dist/chunk-QOZKPLVJ.js +226 -0
  42. package/dist/chunk-QY22NZUW.js +1764 -0
  43. package/dist/chunk-RA3O54FC.js +30 -0
  44. package/dist/chunk-RFUPN6KX.js +71 -0
  45. package/dist/chunk-SY4GK4SP.js +55 -0
  46. package/dist/chunk-TBT347UY.js +41 -0
  47. package/dist/chunk-TWNWNS2Q.js +1084 -0
  48. package/dist/{chunk-NXLLURA4.js → chunk-UFFXNXLQ.js} +115 -71
  49. package/dist/chunk-USO2DKBD.js +421 -0
  50. package/dist/chunk-W4SQCOZU.js +206 -0
  51. package/dist/{chunk-Q6CL5THG.js → chunk-W5FVUZXV.js} +208 -61
  52. package/dist/chunk-WFJ65NUD.js +383 -0
  53. package/dist/{chunk-A3WLZX2F.js → chunk-WIOZAJ2W.js} +15 -2
  54. package/dist/chunk-WO2BXCTQ.js +83 -0
  55. package/dist/{chunk-I3ETLSNE.js → chunk-XCCLFVXM.js} +120 -11
  56. package/dist/{context-materialize-6WKT3RBQ.js → chunk-XDDW4FRS.js} +134 -26
  57. package/dist/chunk-Y7KJLXYN.js +232 -0
  58. package/dist/chunk-YFHIIH4B.js +102 -0
  59. package/dist/chunk-YYYXRJUW.js +101 -0
  60. package/dist/chunk-ZM2IMMYN.js +76 -0
  61. package/dist/chunk-ZMYPLFG3.js +71 -0
  62. package/dist/chunk-ZNA27WEV.js +470 -0
  63. package/dist/{cli-G7DILYJY.js → cli-W62AFRSW.js} +616 -878
  64. package/dist/{paths-D2VGWWFI.js → cli-build-K56DK4DS.js} +1 -1
  65. package/dist/config-XVJYZ4IQ.js +9 -0
  66. package/dist/connect-cmd-ZTJONP37.js +16 -0
  67. package/dist/context-adopt-UMA4O5NY.js +105 -0
  68. package/dist/context-materialize-G2FUFC72.js +19 -0
  69. package/dist/dist-44CQVWGT.js +6 -0
  70. package/dist/docker-NEGDLU6D.js +7 -0
  71. package/dist/doctor-53F2PYY7.js +43 -0
  72. package/dist/doctor-ZLGZYMDK.js +426 -0
  73. package/dist/{emit-artifact-cmd-UQVT3OKW.js → emit-artifact-cmd-AKZP7TMF.js} +87 -23
  74. package/dist/emit-cmd-DCERAU27.js +9 -0
  75. package/dist/emit-criteria-cmd-7MXQVCKD.js +166 -0
  76. package/dist/{emit-finding-cmd-FDOU2OPD.js → emit-finding-cmd-N2FTGCVC.js} +34 -31
  77. package/dist/{emit-result-cmd-H2T4C2K3.js → emit-result-cmd-4CPDBMN2.js} +34 -62
  78. package/dist/exec-client-4XGXV3XN.js +8 -0
  79. package/dist/guest-init-GENRHNP7.js +8 -0
  80. package/dist/hook-fast-EYENPK6F.js +9 -0
  81. package/dist/{hook-wrap-fast-KXYNX3AD.js → hook-wrap-fast-NPLHJXFK.js} +2 -2
  82. package/dist/host-key-KDYZ5ECC.js +7 -0
  83. package/dist/import-capture-cmd-AVZ4VIVJ.js +68 -0
  84. package/dist/{import-ruler-cmd-7LH2QOMG.js → import-ruler-cmd-GUHL6IY5.js} +1 -1
  85. package/dist/index.js +4 -4
  86. package/dist/init-55Y4LHWF.js +36 -0
  87. package/dist/init-XXEKWZQP.js +221 -0
  88. package/dist/init-cmd-WLST2F7G.js +135 -0
  89. package/dist/install-cmd-7WXOIFDO.js +55 -0
  90. package/dist/lima-XN65D7GN.js +55 -0
  91. package/dist/login-browser-7XGSV7MA.js +10 -0
  92. package/dist/{config-POF7DEQW.js → logout-cmd-QAUFDJ6J.js} +3 -1
  93. package/dist/{logs-TRNPQM42.js → logs-7RYUH5A6.js} +1 -1
  94. package/dist/loop-JFIBP4B7.js +43 -0
  95. package/dist/machine-ZBPT2J3R.js +35 -0
  96. package/dist/mcp-install-cmd-RLK4SO3N.js +9 -0
  97. package/dist/{mcp-serve-cmd-57EZZOTL.js → mcp-serve-cmd-N6UD2KBX.js} +20 -9
  98. package/dist/paths-OYKMVYJP.js +6 -0
  99. package/dist/{pidfile-PTW76F56.js → pidfile-UZRH774M.js} +2 -3
  100. package/dist/real-deps-SU24ZA2K.js +21 -0
  101. package/dist/relay-L76HDX72.js +46 -0
  102. package/dist/settings-J2652U5N.js +7 -0
  103. package/dist/starter-pack-LIZYMKYQ.js +10 -0
  104. package/dist/{status-I27IST4L.js → status-UJXWZRN5.js} +30 -13
  105. package/dist/{statusline-fast-3C5OXHDD.js → statusline-fast-SVTMBMD7.js} +3 -2
  106. package/dist/sync-cmd-4G4A7EVN.js +28 -0
  107. package/dist/version-BWM6VLDI.js +6 -0
  108. package/dist/{watch-3DTPJETH.js → watch-7SKJKGAA.js} +19 -8
  109. package/dist/{work-claim-cmd-5AUNCLS2.js → work-claim-cmd-5F7VZ42N.js} +34 -21
  110. package/dist/work-cmd-QAUZ7MTD.js +17 -0
  111. package/dist/work-comment-cmd-BNCSBTLH.js +106 -0
  112. package/dist/{work-launch-LT663PB3.js → work-launch-YI4CJDAP.js} +1 -1
  113. package/dist/work-open-pr-cmd-VFYZHIIW.js +156 -0
  114. package/dist/work-pr-cmd-PV32ZLSI.js +16 -0
  115. package/package.json +13 -3
  116. package/skill-pack/maintained/amend/SKILL.md +104 -0
  117. package/skill-pack/maintained/emitting-evidence/SKILL.md +108 -0
  118. package/skill-pack/maintained/emitting-evidence/references/agents-snippet.md +20 -0
  119. package/skill-pack/maintained/outerlayer/SKILL.md +55 -0
  120. package/skill-pack/maintained/reporting-findings/SKILL.md +148 -0
  121. package/skill-pack/template/build/SKILL.md +193 -0
  122. package/skill-pack/template/build/references/agent-briefs.md +243 -0
  123. package/skill-pack/template/build/references/criteria-judge.md +91 -0
  124. package/skill-pack/template/build/references/evidence.md +42 -0
  125. package/skill-pack/template/build/references/release.md +74 -0
  126. package/skill-pack/template/build/references/review-briefs.md +275 -0
  127. package/skill-pack/template/build/references/review-loop.md +158 -0
  128. package/skill-pack/template/build/scripts/record-criteria.mjs +235 -0
  129. package/skill-pack/template/spec/SKILL.md +84 -0
  130. package/skill-pack/template/writing-specs/SKILL.md +134 -0
  131. package/dist/chunk-DCNOXRMV.js +0 -589
  132. package/dist/chunk-JJP7YLMN.js +0 -25
  133. package/dist/chunk-OZ7C3XUE.js +0 -34
  134. package/dist/chunk-WQ6VGRGZ.js +0 -150
  135. package/dist/hook-fast-J5LCDHUJ.js +0 -8
  136. package/dist/import-capture-cmd-EUMBGIV3.js +0 -176
  137. package/dist/init-PTBITAUO.js +0 -103
  138. package/dist/login-cmd-IRX6LZT7.js +0 -62
  139. package/dist/loop-ASZRX3CZ.js +0 -648
  140. package/dist/sync-cmd-BBAUZ5JD.js +0 -17
  141. package/dist/work-cmd-2P4BVX47.js +0 -18
@@ -0,0 +1,1051 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { hostKeyPath, runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
4
+ import { generateKeyPairSync, createPrivateKey, createPublicKey, sign } from 'crypto';
5
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
6
+
7
+ createRequire(import.meta.url);
8
+
9
+ // ../../node_modules/structured-headers/dist/util.js
10
+ var asciiRe = /^[\x20-\x7E]*$/;
11
+ var tokenRe = /^[a-zA-Z*][:/!#$%&'*+\-.^_`|~A-Za-z0-9]*$/;
12
+ var keyRe = /^[a-z*][*\-_.a-z0-9]*$/;
13
+ function isAscii(str) {
14
+ return asciiRe.test(str);
15
+ }
16
+ function isValidTokenStr(str) {
17
+ return tokenRe.test(str);
18
+ }
19
+ function isValidKeyStr(str) {
20
+ return keyRe.test(str);
21
+ }
22
+ function isInnerList(input) {
23
+ return Array.isArray(input[0]);
24
+ }
25
+ function arrayBufferToBase64(ab) {
26
+ const bytes = new Uint8Array(ab);
27
+ let binary = "";
28
+ for (const byte of bytes) {
29
+ binary += String.fromCharCode(byte);
30
+ }
31
+ return btoa(binary);
32
+ }
33
+ function base64ToArrayBuffer(b64) {
34
+ const binaryString = atob(b64);
35
+ const len = binaryString.length;
36
+ const bytes = new Uint8Array(len);
37
+ for (let i = 0; i < len; i++) {
38
+ bytes[i] = binaryString.charCodeAt(i);
39
+ }
40
+ return bytes.buffer;
41
+ }
42
+
43
+ // ../../node_modules/structured-headers/dist/token.js
44
+ var Token = class {
45
+ constructor(value) {
46
+ if (!isValidTokenStr(value)) {
47
+ throw new TypeError("Invalid character in Token string. Tokens must start with *, A-Z and the rest of the string may only contain a-z, A-Z, 0-9, :/!#$%&'*+-.^_`|~");
48
+ }
49
+ this.value = value;
50
+ }
51
+ toString() {
52
+ return this.value;
53
+ }
54
+ };
55
+
56
+ // ../../node_modules/structured-headers/dist/displaystring.js
57
+ var DisplayString = class {
58
+ constructor(value) {
59
+ this.value = value;
60
+ }
61
+ toString() {
62
+ return this.value;
63
+ }
64
+ };
65
+
66
+ // ../../node_modules/structured-headers/dist/serializer.js
67
+ var SerializeError = class extends Error {
68
+ };
69
+ function serializeDictionary(input) {
70
+ const entries = input instanceof Map ? input.entries() : Object.entries(input);
71
+ return Array.from(entries).map(([key, entry]) => {
72
+ const keyStr = serializeKey(key);
73
+ if (Array.isArray(entry)) {
74
+ if (entry[0] === true) {
75
+ return keyStr + serializeParameters(entry[1]);
76
+ } else {
77
+ if (isInnerList(entry)) {
78
+ return keyStr + "=" + serializeInnerList(entry);
79
+ } else {
80
+ return keyStr + "=" + serializeItem(entry);
81
+ }
82
+ }
83
+ } else {
84
+ if (entry === true) {
85
+ return keyStr;
86
+ } else {
87
+ return keyStr + "=" + serializeBareItem(entry);
88
+ }
89
+ }
90
+ }).join(", ");
91
+ }
92
+ function serializeItem(input, params) {
93
+ if (Array.isArray(input)) {
94
+ return serializeBareItem(input[0]) + serializeParameters(input[1]);
95
+ } else {
96
+ return serializeBareItem(input) + (params ? serializeParameters(params) : "");
97
+ }
98
+ }
99
+ function serializeInnerList(input) {
100
+ return `(${input[0].map((value) => serializeItem(value)).join(" ")})${serializeParameters(input[1])}`;
101
+ }
102
+ function serializeBareItem(input) {
103
+ if (typeof input === "number") {
104
+ if (Number.isInteger(input)) {
105
+ return serializeInteger(input);
106
+ }
107
+ return serializeDecimal(input);
108
+ }
109
+ if (typeof input === "string") {
110
+ return serializeString(input);
111
+ }
112
+ if (input instanceof Token) {
113
+ return serializeToken(input);
114
+ }
115
+ if (input instanceof ArrayBuffer) {
116
+ return serializeByteSequence(input);
117
+ }
118
+ if (input instanceof DisplayString) {
119
+ return serializeDisplayString(input);
120
+ }
121
+ if (input instanceof Date) {
122
+ return serializeDate(input);
123
+ }
124
+ if (typeof input === "boolean") {
125
+ return serializeBoolean(input);
126
+ }
127
+ throw new SerializeError(`Cannot serialize values of type ${typeof input}`);
128
+ }
129
+ function serializeInteger(input) {
130
+ if (input < -999999999999999 || input > 999999999999999) {
131
+ throw new SerializeError("Structured headers can only encode integers in the range range of -999,999,999,999,999 to 999,999,999,999,999 inclusive");
132
+ }
133
+ return input.toString();
134
+ }
135
+ function serializeDecimal(input) {
136
+ const out = input.toFixed(3).replace(/0+$/, "");
137
+ const signifantDigits = out.split(".")[0].replace("-", "").length;
138
+ if (signifantDigits > 12) {
139
+ throw new SerializeError("Fractional numbers are not allowed to have more than 12 significant digits before the decimal point");
140
+ }
141
+ return out;
142
+ }
143
+ function serializeString(input) {
144
+ if (!isAscii(input)) {
145
+ throw new SerializeError("Only ASCII strings may be serialized");
146
+ }
147
+ return `"${input.replace(/("|\\)/g, (v) => "\\" + v)}"`;
148
+ }
149
+ function serializeDisplayString(input) {
150
+ let out = '%"';
151
+ const textEncoder = new TextEncoder();
152
+ for (const char of textEncoder.encode(input.toString())) {
153
+ if (char === 37 || char === 34 || char <= 31 || char >= 127) {
154
+ out += "%" + char.toString(16);
155
+ } else {
156
+ out += String.fromCharCode(char);
157
+ }
158
+ }
159
+ return out + '"';
160
+ }
161
+ function serializeBoolean(input) {
162
+ return input ? "?1" : "?0";
163
+ }
164
+ function serializeByteSequence(input) {
165
+ return `:${arrayBufferToBase64(input)}:`;
166
+ }
167
+ function serializeToken(input) {
168
+ return input.toString();
169
+ }
170
+ function serializeDate(input) {
171
+ return "@" + Math.floor(input.getTime() / 1e3);
172
+ }
173
+ function serializeParameters(input) {
174
+ return Array.from(input).map(([key, value]) => {
175
+ let out = ";" + serializeKey(key);
176
+ if (value !== true) {
177
+ out += "=" + serializeBareItem(value);
178
+ }
179
+ return out;
180
+ }).join("");
181
+ }
182
+ function serializeKey(input) {
183
+ if (!isValidKeyStr(input)) {
184
+ throw new SerializeError("Keys in dictionaries must only contain lowercase letter, numbers, _-*. and must start with a letter or *");
185
+ }
186
+ return input;
187
+ }
188
+
189
+ // ../../node_modules/structured-headers/dist/parser.js
190
+ function parseDictionary(input) {
191
+ const parser = new Parser(input);
192
+ return parser.parseDictionary();
193
+ }
194
+ var ParseError = class extends Error {
195
+ constructor(position, message) {
196
+ super(`Parse error: ${message} at offset ${position}`);
197
+ }
198
+ };
199
+ var Parser = class {
200
+ constructor(input) {
201
+ this.input = input;
202
+ this.pos = 0;
203
+ }
204
+ parseDictionary() {
205
+ this.skipWS();
206
+ const dictionary = /* @__PURE__ */ new Map();
207
+ while (!this.eof()) {
208
+ const thisKey = this.parseKey();
209
+ let member;
210
+ if (this.lookChar() === "=") {
211
+ this.pos++;
212
+ member = this.parseItemOrInnerList();
213
+ } else {
214
+ member = [true, this.parseParameters()];
215
+ }
216
+ dictionary.set(thisKey, member);
217
+ this.skipOWS();
218
+ if (this.eof()) {
219
+ return dictionary;
220
+ }
221
+ this.expectChar(",");
222
+ this.pos++;
223
+ this.skipOWS();
224
+ if (this.eof()) {
225
+ throw new ParseError(this.pos, "Dictionary contained a trailing comma");
226
+ }
227
+ }
228
+ return dictionary;
229
+ }
230
+ parseList() {
231
+ this.skipWS();
232
+ const members = [];
233
+ while (!this.eof()) {
234
+ members.push(this.parseItemOrInnerList());
235
+ this.skipOWS();
236
+ if (this.eof()) {
237
+ return members;
238
+ }
239
+ this.expectChar(",");
240
+ this.pos++;
241
+ this.skipOWS();
242
+ if (this.eof()) {
243
+ throw new ParseError(this.pos, "A list may not end with a trailing comma");
244
+ }
245
+ }
246
+ return members;
247
+ }
248
+ parseItem(standaloneItem = true) {
249
+ if (standaloneItem)
250
+ this.skipWS();
251
+ const result = [
252
+ this.parseBareItem(),
253
+ this.parseParameters()
254
+ ];
255
+ if (standaloneItem)
256
+ this.checkTrail();
257
+ return result;
258
+ }
259
+ parseItemOrInnerList() {
260
+ if (this.lookChar() === "(") {
261
+ return this.parseInnerList();
262
+ } else {
263
+ return this.parseItem(false);
264
+ }
265
+ }
266
+ parseInnerList() {
267
+ this.expectChar("(");
268
+ this.pos++;
269
+ const innerList = [];
270
+ while (!this.eof()) {
271
+ this.skipWS();
272
+ if (this.lookChar() === ")") {
273
+ this.pos++;
274
+ return [
275
+ innerList,
276
+ this.parseParameters()
277
+ ];
278
+ }
279
+ innerList.push(this.parseItem(false));
280
+ const nextChar = this.lookChar();
281
+ if (nextChar !== " " && nextChar !== ")") {
282
+ throw new ParseError(this.pos, "Expected a whitespace or ) after every item in an inner list");
283
+ }
284
+ }
285
+ throw new ParseError(this.pos, "Could not find end of inner list");
286
+ }
287
+ parseBareItem() {
288
+ const char = this.lookChar();
289
+ if (char === void 0) {
290
+ throw new ParseError(this.pos, "Unexpected end of string");
291
+ }
292
+ if (char.match(/^[-0-9]/)) {
293
+ return this.parseIntegerOrDecimal();
294
+ }
295
+ if (char === '"') {
296
+ return this.parseString();
297
+ }
298
+ if (char.match(/^[A-Za-z*]/)) {
299
+ return this.parseToken();
300
+ }
301
+ if (char === ":") {
302
+ return this.parseByteSequence();
303
+ }
304
+ if (char === "?") {
305
+ return this.parseBoolean();
306
+ }
307
+ if (char === "@") {
308
+ return this.parseDate();
309
+ }
310
+ if (char === "%") {
311
+ return this.parseDisplayString();
312
+ }
313
+ throw new ParseError(this.pos, "Unexpected input");
314
+ }
315
+ parseParameters() {
316
+ const parameters = /* @__PURE__ */ new Map();
317
+ while (!this.eof()) {
318
+ const char = this.lookChar();
319
+ if (char !== ";") {
320
+ break;
321
+ }
322
+ this.pos++;
323
+ this.skipWS();
324
+ const key = this.parseKey();
325
+ let value = true;
326
+ if (this.lookChar() === "=") {
327
+ this.pos++;
328
+ value = this.parseBareItem();
329
+ }
330
+ parameters.set(key, value);
331
+ }
332
+ return parameters;
333
+ }
334
+ parseIntegerOrDecimal() {
335
+ let type = "integer";
336
+ let sign = 1;
337
+ let inputNumber = "";
338
+ if (this.lookChar() === "-") {
339
+ sign = -1;
340
+ this.pos++;
341
+ }
342
+ if (!isDigit(this.lookChar())) {
343
+ throw new ParseError(this.pos, "Expected a digit (0-9)");
344
+ }
345
+ while (!this.eof()) {
346
+ const char = this.getChar();
347
+ if (isDigit(char)) {
348
+ inputNumber += char;
349
+ } else if (type === "integer" && char === ".") {
350
+ if (inputNumber.length > 12) {
351
+ throw new ParseError(this.pos, "Exceeded maximum decimal length");
352
+ }
353
+ inputNumber += ".";
354
+ type = "decimal";
355
+ } else {
356
+ this.pos--;
357
+ break;
358
+ }
359
+ if (type === "integer" && inputNumber.length > 15) {
360
+ throw new ParseError(this.pos, "Exceeded maximum integer length");
361
+ }
362
+ if (type === "decimal" && inputNumber.length > 16) {
363
+ throw new ParseError(this.pos, "Exceeded maximum decimal length");
364
+ }
365
+ }
366
+ if (type === "integer") {
367
+ return parseInt(inputNumber, 10) * sign;
368
+ } else {
369
+ if (inputNumber.endsWith(".")) {
370
+ throw new ParseError(this.pos, "Decimal cannot end on a period");
371
+ }
372
+ if (inputNumber.split(".")[1].length > 3) {
373
+ throw new ParseError(this.pos, "Number of digits after the decimal point cannot exceed 3");
374
+ }
375
+ return parseFloat(inputNumber) * sign;
376
+ }
377
+ }
378
+ parseString() {
379
+ let outputString = "";
380
+ this.expectChar('"');
381
+ this.pos++;
382
+ while (!this.eof()) {
383
+ const char = this.getChar();
384
+ if (char === "\\") {
385
+ if (this.eof()) {
386
+ throw new ParseError(this.pos, "Unexpected end of input");
387
+ }
388
+ const nextChar = this.getChar();
389
+ if (nextChar !== "\\" && nextChar !== '"') {
390
+ throw new ParseError(this.pos, "A backslash must be followed by another backslash or double quote");
391
+ }
392
+ outputString += nextChar;
393
+ } else if (char === '"') {
394
+ return outputString;
395
+ } else if (!isAscii(char)) {
396
+ throw new ParseError(this.pos, "Strings must be in the ASCII range");
397
+ } else {
398
+ outputString += char;
399
+ }
400
+ }
401
+ throw new ParseError(this.pos, "Unexpected end of input");
402
+ }
403
+ parseDisplayString() {
404
+ const chars = this.getChars(2);
405
+ if (chars !== '%"') {
406
+ throw new ParseError(this.pos, "Unexpected character. Display strings should start with %=");
407
+ }
408
+ const result = [];
409
+ while (!this.eof()) {
410
+ const char = this.getChar();
411
+ if (char.charCodeAt(0) <= 31 || char.charCodeAt(0) >= 127 && char.charCodeAt(0) <= 255) {
412
+ throw new ParseError(this.pos, "Invalid char found in DisplayString. Did you forget to escape?");
413
+ }
414
+ if (char === "%") {
415
+ const hexChars = this.getChars(2);
416
+ if (/^[0-9a-f]{2}$/.test(hexChars)) {
417
+ result.push(parseInt(hexChars, 16));
418
+ } else {
419
+ throw new ParseError(this.pos, `Unexpected sequence after % in DispalyString: "${hexChars}". Note that hexidecimals must be lowercase`);
420
+ }
421
+ continue;
422
+ }
423
+ if (char === '"') {
424
+ const textDecoder = new TextDecoder("utf-8", {
425
+ fatal: true
426
+ });
427
+ try {
428
+ return new DisplayString(textDecoder.decode(new Uint8Array(result)));
429
+ } catch {
430
+ throw new ParseError(this.pos, "Fatal error decoding UTF-8 sequence in Display String");
431
+ }
432
+ }
433
+ result.push(char.charCodeAt(0));
434
+ }
435
+ throw new ParseError(this.pos, "Unexpected end of input");
436
+ }
437
+ parseToken() {
438
+ let outputString = "";
439
+ while (!this.eof()) {
440
+ const char = this.lookChar();
441
+ if (char === void 0 || !/^[:/!#$%&'*+\-.^_`|~A-Za-z0-9]$/.test(char)) {
442
+ return new Token(outputString);
443
+ }
444
+ outputString += this.getChar();
445
+ }
446
+ return new Token(outputString);
447
+ }
448
+ parseByteSequence() {
449
+ this.expectChar(":");
450
+ this.pos++;
451
+ const endPos = this.input.indexOf(":", this.pos);
452
+ if (endPos === -1) {
453
+ throw new ParseError(this.pos, 'Could not find a closing ":" character to mark end of Byte Sequence');
454
+ }
455
+ const b64Content = this.input.substring(this.pos, endPos);
456
+ this.pos += b64Content.length + 1;
457
+ if (!/^[A-Za-z0-9+/=]*$/.test(b64Content)) {
458
+ throw new ParseError(this.pos, "ByteSequence does not contain a valid base64 string");
459
+ }
460
+ try {
461
+ return base64ToArrayBuffer(b64Content);
462
+ } catch {
463
+ throw new ParseError(this.pos, "ByteSequence does not contain a valid base64 string");
464
+ }
465
+ }
466
+ parseBoolean() {
467
+ this.expectChar("?");
468
+ this.pos++;
469
+ const char = this.getChar();
470
+ if (char === "1") {
471
+ return true;
472
+ }
473
+ if (char === "0") {
474
+ return false;
475
+ }
476
+ throw new ParseError(this.pos, 'Unexpected character. Expected a "1" or a "0"');
477
+ }
478
+ parseDate() {
479
+ this.expectChar("@");
480
+ this.pos++;
481
+ let sign = 1;
482
+ let inputNumber = "";
483
+ if (this.lookChar() === "-") {
484
+ sign = -1;
485
+ this.pos++;
486
+ }
487
+ if (!isDigit(this.lookChar())) {
488
+ throw new ParseError(this.pos, "Expected a digit (0-9)");
489
+ }
490
+ while (!this.eof()) {
491
+ const char = this.getChar();
492
+ if (isDigit(char)) {
493
+ inputNumber += char;
494
+ } else {
495
+ throw new ParseError(this.pos, "Expected a digit (0-9), whitespace or EOL");
496
+ }
497
+ }
498
+ if (inputNumber.length > 15) {
499
+ throw new ParseError(this.pos, "Exceeded max length for a date value");
500
+ }
501
+ return new Date(parseInt(inputNumber, 10) * sign * 1e3);
502
+ }
503
+ parseKey() {
504
+ if (!this.lookChar()?.match(/^[a-z*]/)) {
505
+ throw new ParseError(this.pos, "A key must begin with an asterisk or letter (a-z)");
506
+ }
507
+ let outputString = "";
508
+ while (!this.eof()) {
509
+ const char = this.lookChar();
510
+ if (char === void 0 || !/^[a-z0-9_\-.*]$/.test(char)) {
511
+ return outputString;
512
+ }
513
+ outputString += this.getChar();
514
+ }
515
+ return outputString;
516
+ }
517
+ /**
518
+ * Looks at the next character without advancing the cursor.
519
+ *
520
+ * Returns undefined if we were at the end of the string.
521
+ */
522
+ lookChar() {
523
+ return this.input[this.pos];
524
+ }
525
+ /**
526
+ * Checks if the next character is 'char', and fail otherwise.
527
+ */
528
+ expectChar(char) {
529
+ if (this.lookChar() !== char) {
530
+ throw new ParseError(this.pos, `Expected ${char}`);
531
+ }
532
+ }
533
+ getChar() {
534
+ return this.input[this.pos++];
535
+ }
536
+ getChars(count) {
537
+ const result = this.input.substr(this.pos, count);
538
+ this.pos += count;
539
+ return result;
540
+ }
541
+ eof() {
542
+ return this.pos >= this.input.length;
543
+ }
544
+ // Advances the pointer to skip all whitespace.
545
+ skipOWS() {
546
+ while (true) {
547
+ const c = this.input.substr(this.pos, 1);
548
+ if (c === " " || c === " ") {
549
+ this.pos++;
550
+ } else {
551
+ break;
552
+ }
553
+ }
554
+ }
555
+ // Advances the pointer to skip all spaces
556
+ skipWS() {
557
+ while (this.lookChar() === " ") {
558
+ this.pos++;
559
+ }
560
+ }
561
+ // At the end of parsing, we need to make sure there are no bytes after the
562
+ // header except whitespace.
563
+ checkTrail() {
564
+ this.skipWS();
565
+ if (!this.eof()) {
566
+ throw new ParseError(this.pos, "Unexpected characters at end of input");
567
+ }
568
+ }
569
+ };
570
+ var isDigitRegex = /^[0-9]$/;
571
+ function isDigit(char) {
572
+ if (char === void 0)
573
+ return false;
574
+ return isDigitRegex.test(char);
575
+ }
576
+
577
+ // ../../node_modules/http-message-sig/dist/index.mjs
578
+ var SignatureErrorCode = Object.freeze({
579
+ MissingField: "MissingField",
580
+ MalformedField: "MalformedField",
581
+ LabelRequired: "LabelRequired",
582
+ LabelMismatch: "LabelMismatch",
583
+ DuplicateLabel: "DuplicateLabel",
584
+ InvalidComponent: "InvalidComponent",
585
+ DuplicateComponent: "DuplicateComponent",
586
+ UnsupportedFeature: "UnsupportedFeature",
587
+ AlgorithmMismatch: "AlgorithmMismatch",
588
+ PolicyViolation: "PolicyViolation",
589
+ VerificationFailed: "VerificationFailed",
590
+ ResolverFailed: "ResolverFailed"
591
+ });
592
+ var SignatureError = class extends Error {
593
+ constructor(code, message, cause) {
594
+ super(message);
595
+ this.name = "SignatureError";
596
+ this.code = code;
597
+ this.cause = cause;
598
+ }
599
+ };
600
+ var encoder = new TextEncoder();
601
+ var fieldNamePattern = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
602
+ var sfKeyPattern = /^[a-z*][a-z0-9_.*-]*$/;
603
+ var derivedComponents = /* @__PURE__ */ new Set([
604
+ "@method",
605
+ "@target-uri",
606
+ "@authority",
607
+ "@scheme",
608
+ "@request-target",
609
+ "@path",
610
+ "@query",
611
+ "@status"
612
+ ]);
613
+ var unsupportedParameters = /* @__PURE__ */ new Set([
614
+ "sf",
615
+ "bs",
616
+ "tr"
617
+ ]);
618
+ function fail(code, message, cause) {
619
+ throw new SignatureError(code, message, cause);
620
+ }
621
+ function cloneBareItem(value) {
622
+ if (value instanceof ArrayBuffer) return value.slice(0);
623
+ return value;
624
+ }
625
+ function validateParameterName(name) {
626
+ if (!sfKeyPattern.test(name)) fail(SignatureErrorCode.MalformedField, `Invalid parameter name ${name}`);
627
+ }
628
+ function validateSerializableBareItem(value, location) {
629
+ try {
630
+ serializeItem(value);
631
+ } catch (error) {
632
+ fail(SignatureErrorCode.MalformedField, `Invalid ${location}`, error);
633
+ }
634
+ }
635
+ function isRfc8941BareItem(value) {
636
+ return !(value instanceof Date) && !(value instanceof DisplayString);
637
+ }
638
+ function validateBareItem(value, location) {
639
+ if (!isRfc8941BareItem(value)) return fail(SignatureErrorCode.UnsupportedFeature, `${location} uses an RFC 9651-only value`);
640
+ return cloneBareItem(value);
641
+ }
642
+ function copyParameters(input) {
643
+ const output = {};
644
+ for (const [name, value] of Object.entries(input)) {
645
+ validateParameterName(name);
646
+ if (value !== void 0) {
647
+ validateSerializableBareItem(value, `parameter ${name}`);
648
+ output[name] = cloneBareItem(value);
649
+ }
650
+ }
651
+ validateKnownParameters(output);
652
+ return Object.freeze(output);
653
+ }
654
+ function validateKnownParameters(parameters) {
655
+ for (const name of ["created", "expires"]) {
656
+ const value = parameters[name];
657
+ if (value !== void 0 && (!Number.isInteger(value) || typeof value !== "number")) fail(SignatureErrorCode.MalformedField, `${name} must be an integer`);
658
+ }
659
+ for (const name of [
660
+ "nonce",
661
+ "alg",
662
+ "keyid",
663
+ "tag"
664
+ ]) {
665
+ const value = parameters[name];
666
+ if (value !== void 0 && typeof value !== "string") fail(SignatureErrorCode.MalformedField, `${name} must be a string`);
667
+ }
668
+ }
669
+ function parametersToMap(parameters) {
670
+ const output = /* @__PURE__ */ new Map();
671
+ for (const [name, value] of Object.entries(parameters)) if (value !== void 0) output.set(name, cloneBareItem(value));
672
+ return output;
673
+ }
674
+ function component(name, parameters = {}) {
675
+ const normalizedName = normalizeComponentName(name);
676
+ const copied = copyComponentParameters(parameters);
677
+ validateComponent({
678
+ name: normalizedName,
679
+ parameters: copied
680
+ });
681
+ return Object.freeze({
682
+ name: normalizedName,
683
+ parameters: copied
684
+ });
685
+ }
686
+ function copyComponentParameters(parameters) {
687
+ const output = {};
688
+ for (const [name, value] of Object.entries(parameters)) {
689
+ validateParameterName(name);
690
+ if (value !== void 0) {
691
+ validateSerializableBareItem(value, `component parameter ${name}`);
692
+ output[name] = cloneBareItem(value);
693
+ }
694
+ }
695
+ return Object.freeze(output);
696
+ }
697
+ function normalizeComponentName(name) {
698
+ const normalized = name.toLowerCase();
699
+ if (normalized.startsWith("@")) {
700
+ if (normalized === "@query-param") return fail(SignatureErrorCode.UnsupportedFeature, "@query-param is not supported");
701
+ if (!derivedComponents.has(normalized)) return fail(SignatureErrorCode.UnsupportedFeature, `Unknown derived component ${normalized}`);
702
+ } else if (!fieldNamePattern.test(normalized)) return fail(SignatureErrorCode.InvalidComponent, `Invalid field component ${name}`);
703
+ return normalized;
704
+ }
705
+ function normalizeComponent(input) {
706
+ return typeof input === "string" ? component(input) : component(input.name, input.parameters);
707
+ }
708
+ function validateComponent(value) {
709
+ const entries = Object.entries(value.parameters);
710
+ for (const [name, parameterValue] of entries) {
711
+ if (unsupportedParameters.has(name)) fail(SignatureErrorCode.UnsupportedFeature, `${name} is not supported`);
712
+ if (name !== "req" && name !== "key") fail(SignatureErrorCode.UnsupportedFeature, `Component parameter ${name} is not supported`);
713
+ if (name === "req" && parameterValue !== true) fail(SignatureErrorCode.InvalidComponent, "req must be true");
714
+ if (name === "key" && typeof parameterValue !== "string") fail(SignatureErrorCode.InvalidComponent, "key must be a string");
715
+ }
716
+ if (value.name.startsWith("@") && value.parameters.key !== void 0) fail(SignatureErrorCode.InvalidComponent, `key is invalid on derived component ${value.name}`);
717
+ }
718
+ function componentMap(value) {
719
+ const output = /* @__PURE__ */ new Map();
720
+ for (const [name, parameterValue] of Object.entries(value.parameters)) if (parameterValue !== void 0) output.set(name, parameterValue);
721
+ return output;
722
+ }
723
+ function equivalentIdentity(input) {
724
+ const ordered = Object.entries(input.parameters).filter((entry) => entry[1] !== void 0).sort(([left], [right]) => left.localeCompare(right));
725
+ const parameters = /* @__PURE__ */ new Map();
726
+ for (const [name, value] of ordered) if (value !== void 0) parameters.set(name, value);
727
+ return serializeItem(input.name, parameters);
728
+ }
729
+ function normalizeComponents(inputs) {
730
+ const output = [];
731
+ const identities = /* @__PURE__ */ new Set();
732
+ for (const input of inputs) {
733
+ const value = normalizeComponent(input);
734
+ const identity = equivalentIdentity(value);
735
+ if (identities.has(identity)) fail(SignatureErrorCode.DuplicateComponent, `Duplicate component ${identity}`);
736
+ identities.add(identity);
737
+ output.push(value);
738
+ }
739
+ return Object.freeze(output);
740
+ }
741
+ function fieldsFromHeaders(headers) {
742
+ const fields = [];
743
+ headers.forEach((value, name) => fields.push(Object.freeze({
744
+ name,
745
+ value
746
+ })));
747
+ return Object.freeze(fields);
748
+ }
749
+ function copyFields(fields) {
750
+ return Object.freeze(fields.map(({ name, value }) => {
751
+ if (!fieldNamePattern.test(name)) fail(SignatureErrorCode.MalformedField, `Invalid field name ${name}`);
752
+ const normalized = normalizeFieldValue(value);
753
+ validateAscii(normalized, `Field ${name}`);
754
+ return Object.freeze({
755
+ name: name.toLowerCase(),
756
+ value: normalized
757
+ });
758
+ }));
759
+ }
760
+ function isNativeRequest(message) {
761
+ return typeof Request !== "undefined" && message instanceof Request;
762
+ }
763
+ function isNativeResponse(message) {
764
+ return typeof Response !== "undefined" && message instanceof Response;
765
+ }
766
+ function snapshotRequest(message) {
767
+ if (isNativeRequest(message)) return Object.freeze({
768
+ kind: "request",
769
+ method: message.method,
770
+ targetUri: message.url,
771
+ fields: fieldsFromHeaders(message.headers),
772
+ trailers: Object.freeze([])
773
+ });
774
+ if (!fieldNamePattern.test(message.method)) fail(SignatureErrorCode.InvalidComponent, "Invalid request method");
775
+ validateAscii(message.targetUri, "Target URI");
776
+ if (message.requestTarget !== void 0) validateAscii(message.requestTarget, "Request target");
777
+ return Object.freeze({
778
+ kind: "request",
779
+ method: message.method,
780
+ targetUri: message.targetUri,
781
+ requestTarget: message.requestTarget,
782
+ fields: copyFields(message.fields),
783
+ trailers: copyFields(message.trailers ?? [])
784
+ });
785
+ }
786
+ function snapshotMessage(message) {
787
+ if (isNativeRequest(message)) return snapshotRequest(message);
788
+ if (isNativeResponse(message)) return Object.freeze({
789
+ kind: "response",
790
+ status: message.status,
791
+ fields: fieldsFromHeaders(message.headers),
792
+ trailers: Object.freeze([])
793
+ });
794
+ return snapshotRequest(message);
795
+ }
796
+ function normalizeFieldValue(value) {
797
+ return value.replace(/\r\n[\t ]+/g, " ").replace(/^[\t ]+|[\t ]+$/g, "");
798
+ }
799
+ function validateAscii(value, location) {
800
+ for (const character of value) {
801
+ const code = character.charCodeAt(0);
802
+ if (code > 126 || code < 32 || code === 127) {
803
+ if (code === 9) continue;
804
+ fail(SignatureErrorCode.MalformedField, `${location} is not ASCII field content`);
805
+ }
806
+ }
807
+ }
808
+ function extractField(snapshot, name, trailers) {
809
+ const values = (snapshot.fields).filter((field) => field.name.toLowerCase() === name).map((field) => normalizeFieldValue(field.value));
810
+ if (values.length === 0) return fail(SignatureErrorCode.MissingField, `Missing field ${name}`);
811
+ return values.join(", ");
812
+ }
813
+ function requestForComponent(snapshot, value) {
814
+ if (value.parameters.req === void 0) return snapshot;
815
+ if (snapshot.kind !== "response" || snapshot.request === void 0) return fail(SignatureErrorCode.InvalidComponent, "req requires a response with a related request");
816
+ return snapshot.request;
817
+ }
818
+ function requestUrl(snapshot, name) {
819
+ try {
820
+ return new URL(snapshot.targetUri);
821
+ } catch (error) {
822
+ return fail(SignatureErrorCode.InvalidComponent, `${name} requires an absolute target URI`, error);
823
+ }
824
+ }
825
+ function requestTarget(snapshot, name) {
826
+ const url = requestUrl(snapshot, name);
827
+ if (url.hash !== "") return fail(SignatureErrorCode.InvalidComponent, `${name} target URI cannot contain a fragment`);
828
+ const schemeEnd = snapshot.targetUri.indexOf("://");
829
+ if (schemeEnd === -1) return fail(SignatureErrorCode.InvalidComponent, `${name} requires an HTTP target URI`);
830
+ const pathStart = snapshot.targetUri.indexOf("/", schemeEnd + 3);
831
+ const queryStart = snapshot.targetUri.indexOf("?", schemeEnd + 3);
832
+ const start = pathStart !== -1 && (queryStart === -1 || pathStart < queryStart) ? pathStart : queryStart;
833
+ const pathEnd = queryStart === -1 ? snapshot.targetUri.length : queryStart;
834
+ return Object.freeze({
835
+ url,
836
+ path: start === -1 || start === queryStart ? "/" : snapshot.targetUri.slice(start, pathEnd),
837
+ query: queryStart === -1 ? "?" : snapshot.targetUri.slice(queryStart)
838
+ });
839
+ }
840
+ function extractDerived(snapshot, name) {
841
+ if (name === "@status") {
842
+ if (snapshot.kind !== "response") return fail(SignatureErrorCode.InvalidComponent, "@status requires a response");
843
+ return snapshot.status.toString();
844
+ }
845
+ if (snapshot.kind !== "request") return fail(SignatureErrorCode.InvalidComponent, `${name} requires a request`);
846
+ if (name === "@method") return snapshot.method;
847
+ const target = requestTarget(snapshot, name);
848
+ switch (name) {
849
+ case "@target-uri":
850
+ return snapshot.targetUri;
851
+ case "@authority":
852
+ return target.url.host;
853
+ case "@scheme":
854
+ return target.url.protocol.slice(0, -1);
855
+ case "@request-target":
856
+ if (snapshot.requestTarget === void 0) return fail(SignatureErrorCode.UnsupportedFeature, "@request-target requires a descriptor requestTarget");
857
+ return snapshot.requestTarget;
858
+ case "@path":
859
+ return target.path;
860
+ case "@query":
861
+ return target.query;
862
+ default:
863
+ return fail(SignatureErrorCode.UnsupportedFeature, `Unknown derived component ${name}`);
864
+ }
865
+ }
866
+ function extractComponentValue(snapshot, value) {
867
+ const selected = requestForComponent(snapshot, value);
868
+ if (value.name.startsWith("@")) return extractDerived(selected, value.name);
869
+ const fieldValue = extractField(selected, value.name);
870
+ const key = value.parameters.key;
871
+ if (key === void 0) return fieldValue;
872
+ if (typeof key !== "string") return fail(SignatureErrorCode.InvalidComponent, "key must be a string");
873
+ const member = parseRfc8941Dictionary(fieldValue, `field ${value.name}`).get(key);
874
+ if (member === void 0) return fail(SignatureErrorCode.MissingField, `Field ${value.name} has no dictionary member ${key}`);
875
+ return isInnerList(member) ? serializeInnerList(member) : serializeItem(member);
876
+ }
877
+ function componentsToInnerList(components, parameters) {
878
+ return [components.map((value) => [value.name, componentMap(value)]), parametersToMap(parameters)];
879
+ }
880
+ function buildSignatureBase(snapshot, components, signatureInput) {
881
+ const lines = components.map((value) => `${serializeItem(value.name, componentMap(value))}: ${extractComponentValue(snapshot, value)}`);
882
+ lines.push(`"@signature-params": ${serializeInnerList(signatureInput)}`);
883
+ return encoder.encode(lines.join("\n"));
884
+ }
885
+ function assertAlgorithm(claimed, actual) {
886
+ if (claimed !== void 0 && claimed !== actual) fail(SignatureErrorCode.AlgorithmMismatch, `Claimed algorithm ${String(claimed)} does not match ${actual}`);
887
+ }
888
+ function createInput(message, label, componentsInput, parametersInput, algorithm) {
889
+ if (!sfKeyPattern.test(label)) fail(SignatureErrorCode.MalformedField, `Invalid signature label ${label}`);
890
+ const snapshot = snapshotMessage(message);
891
+ const components = normalizeComponents(componentsInput);
892
+ const parameters = copyParameters(parametersInput);
893
+ assertAlgorithm(parameters.alg, algorithm);
894
+ const innerList = componentsToInnerList(components, parameters);
895
+ const dictionary = /* @__PURE__ */ new Map([[label, innerList]]);
896
+ return Object.freeze({
897
+ base: buildSignatureBase(snapshot, components, innerList),
898
+ signatureInput: serializeDictionary(dictionary)
899
+ });
900
+ }
901
+ function signatureDictionary(label, signature) {
902
+ const item = [Uint8Array.from(signature).buffer, /* @__PURE__ */ new Map()];
903
+ return serializeDictionary(/* @__PURE__ */ new Map([[label, item]]));
904
+ }
905
+ async function createSignature(message, options) {
906
+ const label = options.label ?? "sig1";
907
+ const input = createInput(message, label, options.components, options.parameters, options.signer.algorithm);
908
+ const signature = await options.signer.sign(input.base.slice());
909
+ return Object.freeze({
910
+ signature: signatureDictionary(label, signature),
911
+ signatureInput: input.signatureInput
912
+ });
913
+ }
914
+ function assertNoRfc9651Syntax(input, name) {
915
+ let quoted = false;
916
+ let escaped = false;
917
+ for (let index = 0; index < input.length; index += 1) {
918
+ const character = input[index];
919
+ if (escaped) {
920
+ escaped = false;
921
+ continue;
922
+ }
923
+ if (quoted && character === "\\") {
924
+ escaped = true;
925
+ continue;
926
+ }
927
+ if (character === '"') {
928
+ quoted = !quoted;
929
+ continue;
930
+ }
931
+ if (!quoted && (character === "@" || character === "%" && input[index + 1] === '"')) fail(SignatureErrorCode.UnsupportedFeature, `${name} uses an RFC 9651-only value`);
932
+ }
933
+ }
934
+ function parseRfc8941Dictionary(input, name) {
935
+ assertNoRfc9651Syntax(input, name);
936
+ let dictionary;
937
+ try {
938
+ dictionary = parseDictionary(input);
939
+ } catch (error) {
940
+ return fail(SignatureErrorCode.MalformedField, `Malformed ${name}`, error);
941
+ }
942
+ assertRfc8941Dictionary(dictionary, name);
943
+ return dictionary;
944
+ }
945
+ function assertRfc8941Dictionary(dictionary, name) {
946
+ for (const member of dictionary.values()) {
947
+ if (isInnerList(member)) for (const [value, parameters] of member[0]) {
948
+ validateBareItem(value, name);
949
+ for (const parameter of parameters.values()) validateBareItem(parameter, name);
950
+ }
951
+ else validateBareItem(member[0], name);
952
+ for (const parameter of member[1].values()) validateBareItem(parameter, name);
953
+ }
954
+ }
955
+
956
+ // ../runner-signature/dist/index.js
957
+ var RUNNER_SIGNATURE_LABEL = "runner";
958
+ var RUNNER_SIGNATURE_ALGORITHM = "ed25519";
959
+ var RUNNER_SIGNED_COMPONENTS = ["@method", "@path", "@query", "content-digest"];
960
+ async function sha256(data) {
961
+ return new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", data));
962
+ }
963
+ function base64FromBytes(bytes) {
964
+ let binary = "";
965
+ for (const byte of bytes) binary += String.fromCharCode(byte);
966
+ return btoa(binary);
967
+ }
968
+ async function contentDigest(body) {
969
+ return `sha-256=:${base64FromBytes(await sha256(body))}:`;
970
+ }
971
+ async function hostKeyFingerprint(publicKeyRaw) {
972
+ return `SHA256:${base64FromBytes(await sha256(publicKeyRaw)).replace(/=+$/, "")}`;
973
+ }
974
+ async function signRunnerRequest(input) {
975
+ var _a, _b;
976
+ const digest = await contentDigest(input.body);
977
+ const fields = await createSignature(
978
+ {
979
+ method: input.method.toUpperCase(),
980
+ targetUri: input.url,
981
+ fields: [{ name: "content-digest", value: digest }]
982
+ },
983
+ {
984
+ label: RUNNER_SIGNATURE_LABEL,
985
+ components: RUNNER_SIGNED_COMPONENTS,
986
+ parameters: {
987
+ created: (_a = input.created) != null ? _a : Math.floor(Date.now() / 1e3),
988
+ nonce: (_b = input.nonce) != null ? _b : globalThis.crypto.randomUUID(),
989
+ keyid: input.signer.keyId,
990
+ alg: RUNNER_SIGNATURE_ALGORITHM
991
+ },
992
+ signer: {
993
+ algorithm: RUNNER_SIGNATURE_ALGORITHM,
994
+ sign: (data) => input.signer.sign(data)
995
+ }
996
+ }
997
+ );
998
+ return {
999
+ signature: fields.signature,
1000
+ "signature-input": fields.signatureInput,
1001
+ "content-digest": digest
1002
+ };
1003
+ }
1004
+
1005
+ // src/runner/host-key.ts
1006
+ var SPKI_ED25519_PREFIX_BYTES = 12;
1007
+ async function toHostKey(privateKey) {
1008
+ const spki = createPublicKey(privateKey).export({ format: "der", type: "spki" });
1009
+ const publicKeyRaw = new Uint8Array(spki.subarray(SPKI_ED25519_PREFIX_BYTES));
1010
+ const hostKey = Buffer.from(publicKeyRaw).toString("base64url");
1011
+ const fingerprint = await hostKeyFingerprint(publicKeyRaw);
1012
+ return {
1013
+ signer: { keyId: fingerprint, sign: (data) => new Uint8Array(sign(null, data, privateKey)) },
1014
+ publicKeyRaw,
1015
+ hostKey,
1016
+ fingerprint
1017
+ };
1018
+ }
1019
+ async function readHostKey(path) {
1020
+ let privateKey;
1021
+ try {
1022
+ privateKey = createPrivateKey(readFileSync(path, "utf8"));
1023
+ } catch (err) {
1024
+ throw new Error(`${path}: the host key cannot be read as a private key (${err instanceof Error ? err.message : String(err)})`);
1025
+ }
1026
+ if (privateKey.asymmetricKeyType !== "ed25519") {
1027
+ throw new Error(`${path}: the host key must be an Ed25519 private key, found ${String(privateKey.asymmetricKeyType)}`);
1028
+ }
1029
+ return toHostKey(privateKey);
1030
+ }
1031
+ async function loadHostKey(configPath) {
1032
+ const path = hostKeyPath(configPath);
1033
+ return existsSync(path) ? readHostKey(path) : void 0;
1034
+ }
1035
+ async function ensureHostKey(configPath) {
1036
+ const path = hostKeyPath(configPath);
1037
+ mkdirSync(runnerDir(configPath), { recursive: true, mode: RUNNER_DIR_MODE });
1038
+ const { privateKey } = generateKeyPairSync("ed25519");
1039
+ try {
1040
+ writeFileSync(path, privateKey.export({ type: "pkcs8", format: "pem" }), { flag: "wx", mode: RUNNER_FILE_MODE });
1041
+ } catch (err) {
1042
+ if (err.code !== "EEXIST") throw err;
1043
+ return readHostKey(path);
1044
+ }
1045
+ return toHostKey(privateKey);
1046
+ }
1047
+ async function signerFor(configPath) {
1048
+ return (await loadHostKey(configPath))?.signer;
1049
+ }
1050
+
1051
+ export { ensureHostKey, loadHostKey, signRunnerRequest, signerFor };