@ascenda-one/agent-mcp 0.1.15 → 0.1.17
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 +1689 -122
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -204,6 +204,102 @@ var require_workMilestoneClassifier = __commonJS({
|
|
|
204
204
|
}
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
+
// ../packages/tool-kit/out/autonomyBand.js
|
|
208
|
+
var require_autonomyBand = __commonJS({
|
|
209
|
+
"../packages/tool-kit/out/autonomyBand.js"(exports) {
|
|
210
|
+
"use strict";
|
|
211
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
212
|
+
exports.autonomyBand = autonomyBand;
|
|
213
|
+
function autonomyBand(mode) {
|
|
214
|
+
if (typeof mode !== "string")
|
|
215
|
+
return "unknown";
|
|
216
|
+
return BAND_BY_MODE[mode] ?? "unknown";
|
|
217
|
+
}
|
|
218
|
+
var BAND_BY_MODE = {
|
|
219
|
+
plan: "planning",
|
|
220
|
+
default: "supervised",
|
|
221
|
+
accept_edits: "edits_auto",
|
|
222
|
+
// Two tokens, one band — and the reason the tokens stayed two. They differ
|
|
223
|
+
// in how the user arrived at the posture rather than in how much the agent
|
|
224
|
+
// may then do unasked, so today they read the same. If that ever stops being
|
|
225
|
+
// true, this line changes and the whole corpus re-reads correctly, because
|
|
226
|
+
// the wire never collapsed them.
|
|
227
|
+
auto: "delegated",
|
|
228
|
+
dont_ask: "delegated",
|
|
229
|
+
bypass_permissions: "unsupervised"
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// ../packages/tool-kit/out/modelClassifier.js
|
|
235
|
+
var require_modelClassifier = __commonJS({
|
|
236
|
+
"../packages/tool-kit/out/modelClassifier.js"(exports) {
|
|
237
|
+
"use strict";
|
|
238
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
239
|
+
exports.classifyModelClass = classifyModelClass;
|
|
240
|
+
function classifyModelClass(raw) {
|
|
241
|
+
const candidate = raw;
|
|
242
|
+
if (candidate === void 0 || candidate === null)
|
|
243
|
+
return void 0;
|
|
244
|
+
if (typeof candidate !== "string")
|
|
245
|
+
return "unknown";
|
|
246
|
+
const value = candidate.trim().toLowerCase();
|
|
247
|
+
if (!value)
|
|
248
|
+
return void 0;
|
|
249
|
+
if (ROUTER_SENTINEL.test(value))
|
|
250
|
+
return "router:auto";
|
|
251
|
+
const vendor = readModelVendor(value);
|
|
252
|
+
if (vendor === void 0)
|
|
253
|
+
return "unknown";
|
|
254
|
+
for (const [pattern, modelClass] of TIER_PATTERNS_BY_VENDOR[vendor]) {
|
|
255
|
+
if (pattern.test(value))
|
|
256
|
+
return modelClass;
|
|
257
|
+
}
|
|
258
|
+
return UNKNOWN_TIER_BY_VENDOR[vendor];
|
|
259
|
+
}
|
|
260
|
+
function readModelVendor(value) {
|
|
261
|
+
for (const [pattern, vendor] of VENDOR_PATTERNS) {
|
|
262
|
+
if (pattern.test(value))
|
|
263
|
+
return vendor;
|
|
264
|
+
}
|
|
265
|
+
return void 0;
|
|
266
|
+
}
|
|
267
|
+
var ROUTER_SENTINEL = /^(?:[a-z0-9][a-z0-9._-]*\/)?(?:auto|default)$/;
|
|
268
|
+
var VENDOR_PATTERNS = [
|
|
269
|
+
[/\b(anthropic|claude|opus|sonnet|haiku|fable)\b/, "anthropic"],
|
|
270
|
+
[/\b(openai|gpt|o[1-9])\b/, "openai"],
|
|
271
|
+
[/\b(google|gemini|vertex)\b/, "google"],
|
|
272
|
+
// xAI carries no corporate prefix in any observed id — the family name is
|
|
273
|
+
// the whole marker, exactly as `claude` and `gemini` are for theirs.
|
|
274
|
+
[/\b(xai|grok)\b/, "xai"],
|
|
275
|
+
[/\b(ollama|llamacpp|on[-_]?device|local)\b/, "local"]
|
|
276
|
+
];
|
|
277
|
+
var TIER_PATTERNS_BY_VENDOR = {
|
|
278
|
+
anthropic: [
|
|
279
|
+
[/\bopus\b/, "anthropic:opus"],
|
|
280
|
+
[/\bsonnet\b/, "anthropic:sonnet"],
|
|
281
|
+
[/\bhaiku\b/, "anthropic:haiku"],
|
|
282
|
+
[/\bfable\b/, "anthropic:fable"]
|
|
283
|
+
],
|
|
284
|
+
openai: [[/\bgpt\b/, "openai:gpt"]],
|
|
285
|
+
google: [[/\bgemini\b/, "google:gemini"]],
|
|
286
|
+
// One tier for now. The line's coding variants (`grok-code-fast-1`) are the
|
|
287
|
+
// same tier word plus a suffix, and splitting them off would be inventing a
|
|
288
|
+
// distinction the ids do not yet draw — `<vendor>:unknown` is waiting for
|
|
289
|
+
// the day one does.
|
|
290
|
+
xai: [[/\bgrok\b/, "xai:grok"]],
|
|
291
|
+
local: [[/\b(ollama|llamacpp|on[-_]?device)\b/, "local:on_device"]]
|
|
292
|
+
};
|
|
293
|
+
var UNKNOWN_TIER_BY_VENDOR = {
|
|
294
|
+
anthropic: "anthropic:unknown",
|
|
295
|
+
openai: "openai:unknown",
|
|
296
|
+
google: "google:unknown",
|
|
297
|
+
xai: "xai:unknown",
|
|
298
|
+
local: "local:unknown"
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
207
303
|
// ../packages/tool-kit/out/buckets.js
|
|
208
304
|
var require_buckets = __commonJS({
|
|
209
305
|
"../packages/tool-kit/out/buckets.js"(exports) {
|
|
@@ -298,89 +394,6 @@ var require_afterHours = __commonJS({
|
|
|
298
394
|
}
|
|
299
395
|
});
|
|
300
396
|
|
|
301
|
-
// ../packages/tool-kit/out/payload.js
|
|
302
|
-
var require_payload = __commonJS({
|
|
303
|
-
"../packages/tool-kit/out/payload.js"(exports) {
|
|
304
|
-
"use strict";
|
|
305
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
306
|
-
exports.getString = getString;
|
|
307
|
-
exports.getNumber = getNumber;
|
|
308
|
-
exports.getNested = getNested;
|
|
309
|
-
exports.getNestedString = getNestedString;
|
|
310
|
-
exports.getNestedNumber = getNestedNumber;
|
|
311
|
-
exports.inferOutcome = inferOutcome;
|
|
312
|
-
exports.outcomeForHook = outcomeForHook;
|
|
313
|
-
exports.looksLikeCorrection = looksLikeCorrection;
|
|
314
|
-
function getString(input, keys) {
|
|
315
|
-
for (const key of keys) {
|
|
316
|
-
const value = input[key];
|
|
317
|
-
if (typeof value === "string" && value.trim())
|
|
318
|
-
return value;
|
|
319
|
-
}
|
|
320
|
-
return void 0;
|
|
321
|
-
}
|
|
322
|
-
function getNumber(input, keys) {
|
|
323
|
-
for (const key of keys) {
|
|
324
|
-
const value = input[key];
|
|
325
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
326
|
-
return value;
|
|
327
|
-
}
|
|
328
|
-
return void 0;
|
|
329
|
-
}
|
|
330
|
-
function getNested(input, path) {
|
|
331
|
-
let current = input;
|
|
332
|
-
for (const segment of path) {
|
|
333
|
-
if (!current || typeof current !== "object")
|
|
334
|
-
return void 0;
|
|
335
|
-
current = current[segment];
|
|
336
|
-
}
|
|
337
|
-
return current;
|
|
338
|
-
}
|
|
339
|
-
function getNestedString(input, paths) {
|
|
340
|
-
for (const path of paths) {
|
|
341
|
-
const value = getNested(input, path);
|
|
342
|
-
if (typeof value === "string" && value.trim())
|
|
343
|
-
return value;
|
|
344
|
-
}
|
|
345
|
-
return void 0;
|
|
346
|
-
}
|
|
347
|
-
function getNestedNumber(input, paths) {
|
|
348
|
-
for (const path of paths) {
|
|
349
|
-
const value = getNested(input, path);
|
|
350
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
351
|
-
return value;
|
|
352
|
-
}
|
|
353
|
-
return void 0;
|
|
354
|
-
}
|
|
355
|
-
function inferOutcome(input) {
|
|
356
|
-
const exitCode = getNumber(input, ["exitCode", "exit_code", "status"]) ?? getNestedNumber(input, [["tool_response", "exitCode"], ["tool_response", "exit_code"], ["result", "exitCode"], ["result", "exit_code"]]);
|
|
357
|
-
if (typeof exitCode === "number")
|
|
358
|
-
return exitCode === 0 ? "success" : "failure";
|
|
359
|
-
const error2 = getString(input, ["error", "errorMessage"]) ?? getNestedString(input, [["tool_response", "error"], ["result", "error"]]);
|
|
360
|
-
if (error2)
|
|
361
|
-
return "failure";
|
|
362
|
-
return "unknown";
|
|
363
|
-
}
|
|
364
|
-
function outcomeForHook(hookName, input) {
|
|
365
|
-
if (hookName === "PostToolUseFailure") {
|
|
366
|
-
const interrupted = input["is_interrupt"] === true || getNested(input, ["tool_response", "interrupted"]) === true;
|
|
367
|
-
return interrupted ? "cancelled" : "failure";
|
|
368
|
-
}
|
|
369
|
-
if (hookName === "PostToolUse") {
|
|
370
|
-
if (getNested(input, ["tool_response", "interrupted"]) === true)
|
|
371
|
-
return "cancelled";
|
|
372
|
-
return "success";
|
|
373
|
-
}
|
|
374
|
-
return "unknown";
|
|
375
|
-
}
|
|
376
|
-
function looksLikeCorrection(text) {
|
|
377
|
-
if (!text)
|
|
378
|
-
return false;
|
|
379
|
-
return /\b(wrong|incorrect|try again|fix|not what i asked|that's not|that is not|redo|regenerate|you missed|doesn't work|does not work)\b/i.test(text);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
|
|
384
397
|
// ../packages/tool-contract/out/metricKeys.js
|
|
385
398
|
var require_metricKeys = __commonJS({
|
|
386
399
|
"../packages/tool-contract/out/metricKeys.js"(exports) {
|
|
@@ -420,6 +433,42 @@ var require_metricKeys = __commonJS({
|
|
|
420
433
|
linesChangedBucket: { readBy: ["backend"], backendAliases: ["linesChangedBucket", "lines_changed_bucket"] },
|
|
421
434
|
// ── Read by the local handoff only ──────────────────────────────────────
|
|
422
435
|
activeMinutes: { readBy: ["handoff"], unit: "minutes" },
|
|
436
|
+
/**
|
|
437
|
+
* The two halves of `activeMinutes`, and deliberately two keys.
|
|
438
|
+
*
|
|
439
|
+
* They partition it exactly, so a reader can add them — but there is no
|
|
440
|
+
* third key holding the sum, because the sum is `activeMinutes` and it
|
|
441
|
+
* already exists. Presenting one combined "active" figure in place of these
|
|
442
|
+
* is the thing the split was added to stop: an hour of typing and an hour of
|
|
443
|
+
* watching an agent work are not the same hour, and a single number says
|
|
444
|
+
* they are.
|
|
445
|
+
*/
|
|
446
|
+
handsOnMinutes: {
|
|
447
|
+
readBy: ["handoff"],
|
|
448
|
+
unit: "minutes",
|
|
449
|
+
note: "Active time immediately preceding a human prompt \u2014 the only interval a transcript can show a person present for, because the prompt at its end is the evidence."
|
|
450
|
+
},
|
|
451
|
+
agentSupervisingMinutes: {
|
|
452
|
+
readBy: ["handoff"],
|
|
453
|
+
unit: "minutes",
|
|
454
|
+
note: "The remaining active time: the agent was working and the person was not typing. NOT a claim that anyone watched it \u2014 nothing in a transcript could show that. Never render as attention."
|
|
455
|
+
},
|
|
456
|
+
// The split's honesty counters. Read by neither the backend nor the handoff
|
|
457
|
+
// on purpose: they exist so a thin or posture-blind session can be told from
|
|
458
|
+
// a complete one, and a reader that ignores them is choosing to, rather than
|
|
459
|
+
// being unable to.
|
|
460
|
+
activeSplitInstants: {
|
|
461
|
+
readBy: ["diagnostic"],
|
|
462
|
+
note: "Distinct timestamps the split ran over, after collapsing ties. The denominator: two minutes off four instants and off four hundred are not the same measurement."
|
|
463
|
+
},
|
|
464
|
+
activeSplitUndatedLines: {
|
|
465
|
+
readBy: ["diagnostic"],
|
|
466
|
+
note: "Known lines carrying a timestamp that would not parse. Absent from the timeline, so both halves are short by an unknown amount and only this says so."
|
|
467
|
+
},
|
|
468
|
+
activeSplitUnposturedInstants: {
|
|
469
|
+
readBy: ["diagnostic"],
|
|
470
|
+
note: "Instants reached before any permissionMode had been declared. Their supervising time lands in the unknown band, which is a blind spot rather than a posture."
|
|
471
|
+
},
|
|
423
472
|
afterHoursRequests: { readBy: ["handoff"] },
|
|
424
473
|
approximateLintErrorsCount: { readBy: ["handoff"] },
|
|
425
474
|
canceledCount: { readBy: ["handoff"] },
|
|
@@ -433,6 +482,11 @@ var require_metricKeys = __commonJS({
|
|
|
433
482
|
unit: "tokens",
|
|
434
483
|
note: "The measured quantity, with no assumed denominator. Prefer this to the ratio for any within-person baseline."
|
|
435
484
|
},
|
|
485
|
+
contextWindowTokens: {
|
|
486
|
+
readBy: ["handoff"],
|
|
487
|
+
unit: "tokens",
|
|
488
|
+
note: "Codex only: the model_context_window the rollout itself recorded \u2014 the real denominator its contextWindowPeakPct was computed against. Claude Code records no window and its ratio assumes 200k; absent here means the store never said."
|
|
489
|
+
},
|
|
436
490
|
date: { readBy: ["handoff"] },
|
|
437
491
|
errorCount: { readBy: ["handoff"] },
|
|
438
492
|
filesChangedCount: { readBy: ["handoff"] },
|
|
@@ -516,6 +570,10 @@ var require_metricKeys = __commonJS({
|
|
|
516
570
|
unparsedLines: { readBy: ["diagnostic"] },
|
|
517
571
|
unreadableChatSessionFiles: { readBy: ["diagnostic"] },
|
|
518
572
|
unreadableHistoryFiles: { readBy: ["diagnostic"] },
|
|
573
|
+
unreadableRolloutFiles: {
|
|
574
|
+
readBy: ["diagnostic"],
|
|
575
|
+
note: "Codex only: rollout files the extractor meant to read and could not open. Summed into the import's read-failure warning, so a store that is partly unreadable says so rather than reporting a short window as the whole."
|
|
576
|
+
},
|
|
519
577
|
unrecognisedChatSessionFiles: { readBy: ["diagnostic"] }
|
|
520
578
|
};
|
|
521
579
|
function backendMetricKeys() {
|
|
@@ -529,7 +587,7 @@ var require_out = __commonJS({
|
|
|
529
587
|
"../packages/tool-contract/out/index.js"(exports) {
|
|
530
588
|
"use strict";
|
|
531
589
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
532
|
-
exports.backendMetricKeys = exports.METRIC_KEYS = exports.ASCENDA_SEMANTIC_PROVENANCE = exports.ASCENDA_HISTORICAL_CONSENT_SCOPE = exports.ASCENDA_COLLABORATION_CONSENT_SCOPE = exports.ASCENDA_SEMANTIC_CONSENT_SCOPE = exports.ASCENDA_PROVENANCE = exports.ASCENDA_CONSENT_SCOPE = exports.EVENT_WORKLOAD_CATEGORY = exports.COLLABORATION_EVENT_TYPES = exports.SEMANTIC_WORK_SIGNAL_EVENT_TYPES = void 0;
|
|
590
|
+
exports.backendMetricKeys = exports.METRIC_KEYS = exports.ASCENDA_SEMANTIC_PROVENANCE = exports.ASCENDA_HISTORICAL_CONSENT_SCOPE = exports.ASCENDA_COLLABORATION_CONSENT_SCOPE = exports.ASCENDA_SEMANTIC_CONSENT_SCOPE = exports.ASCENDA_PROVENANCE = exports.ASCENDA_CONSENT_SCOPE = exports.EVENT_WORKLOAD_CATEGORY = exports.TOOL_EVENT_DELIVERED_STATUSES = exports.IDEMPOTENCY_KEY_MAX_LENGTH = exports.EVENT_METADATA_FIELDS = exports.COLLABORATION_EVENT_TYPES = exports.SEMANTIC_WORK_SIGNAL_EVENT_TYPES = void 0;
|
|
533
591
|
exports.SEMANTIC_WORK_SIGNAL_EVENT_TYPES = [
|
|
534
592
|
"approach_churn_detected",
|
|
535
593
|
"goal_drift_detected",
|
|
@@ -543,6 +601,39 @@ var require_out = __commonJS({
|
|
|
543
601
|
"review_given",
|
|
544
602
|
"pull_request_opened"
|
|
545
603
|
];
|
|
604
|
+
exports.EVENT_METADATA_FIELDS = [
|
|
605
|
+
"language",
|
|
606
|
+
"fileType",
|
|
607
|
+
"durationBucket",
|
|
608
|
+
"tokenPressureBucket",
|
|
609
|
+
"linesChangedBucket",
|
|
610
|
+
"commandClass",
|
|
611
|
+
"gitAction",
|
|
612
|
+
"milestoneKind",
|
|
613
|
+
"branchHash",
|
|
614
|
+
"autonomyMode",
|
|
615
|
+
"modelClass",
|
|
616
|
+
"modelId",
|
|
617
|
+
"userModified",
|
|
618
|
+
"outcome",
|
|
619
|
+
"trigger",
|
|
620
|
+
"promptClass",
|
|
621
|
+
"reason",
|
|
622
|
+
"afterHours",
|
|
623
|
+
"activity",
|
|
624
|
+
"message",
|
|
625
|
+
"host",
|
|
626
|
+
"toolName",
|
|
627
|
+
"simulated",
|
|
628
|
+
"relatedEventType",
|
|
629
|
+
"skillVersion",
|
|
630
|
+
"taskFingerprint",
|
|
631
|
+
"importKey",
|
|
632
|
+
"extractionId",
|
|
633
|
+
"importSchema"
|
|
634
|
+
];
|
|
635
|
+
exports.IDEMPOTENCY_KEY_MAX_LENGTH = 128;
|
|
636
|
+
exports.TOOL_EVENT_DELIVERED_STATUSES = ["accepted", "duplicate"];
|
|
546
637
|
exports.EVENT_WORKLOAD_CATEGORY = {
|
|
547
638
|
create_focus_session: "creation",
|
|
548
639
|
ai_prompt_submitted: "creation",
|
|
@@ -598,6 +689,98 @@ var require_out = __commonJS({
|
|
|
598
689
|
}
|
|
599
690
|
});
|
|
600
691
|
|
|
692
|
+
// ../packages/tool-kit/out/payload.js
|
|
693
|
+
var require_payload = __commonJS({
|
|
694
|
+
"../packages/tool-kit/out/payload.js"(exports) {
|
|
695
|
+
"use strict";
|
|
696
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
697
|
+
exports.mintIdempotencyKey = mintIdempotencyKey;
|
|
698
|
+
exports.getString = getString;
|
|
699
|
+
exports.getNumber = getNumber;
|
|
700
|
+
exports.getNested = getNested;
|
|
701
|
+
exports.getNestedString = getNestedString;
|
|
702
|
+
exports.getNestedNumber = getNestedNumber;
|
|
703
|
+
exports.inferOutcome = inferOutcome;
|
|
704
|
+
exports.outcomeForHook = outcomeForHook;
|
|
705
|
+
exports.looksLikeCorrection = looksLikeCorrection;
|
|
706
|
+
var node_crypto_1 = __require("node:crypto");
|
|
707
|
+
var tool_contract_1 = require_out();
|
|
708
|
+
function mintIdempotencyKey() {
|
|
709
|
+
const key = (0, node_crypto_1.randomUUID)();
|
|
710
|
+
if (key.length > tool_contract_1.IDEMPOTENCY_KEY_MAX_LENGTH)
|
|
711
|
+
throw new Error("idempotency key exceeds the wire limit");
|
|
712
|
+
return key;
|
|
713
|
+
}
|
|
714
|
+
function getString(input, keys) {
|
|
715
|
+
for (const key of keys) {
|
|
716
|
+
const value = input[key];
|
|
717
|
+
if (typeof value === "string" && value.trim())
|
|
718
|
+
return value;
|
|
719
|
+
}
|
|
720
|
+
return void 0;
|
|
721
|
+
}
|
|
722
|
+
function getNumber(input, keys) {
|
|
723
|
+
for (const key of keys) {
|
|
724
|
+
const value = input[key];
|
|
725
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
726
|
+
return value;
|
|
727
|
+
}
|
|
728
|
+
return void 0;
|
|
729
|
+
}
|
|
730
|
+
function getNested(input, path) {
|
|
731
|
+
let current = input;
|
|
732
|
+
for (const segment of path) {
|
|
733
|
+
if (!current || typeof current !== "object")
|
|
734
|
+
return void 0;
|
|
735
|
+
current = current[segment];
|
|
736
|
+
}
|
|
737
|
+
return current;
|
|
738
|
+
}
|
|
739
|
+
function getNestedString(input, paths) {
|
|
740
|
+
for (const path of paths) {
|
|
741
|
+
const value = getNested(input, path);
|
|
742
|
+
if (typeof value === "string" && value.trim())
|
|
743
|
+
return value;
|
|
744
|
+
}
|
|
745
|
+
return void 0;
|
|
746
|
+
}
|
|
747
|
+
function getNestedNumber(input, paths) {
|
|
748
|
+
for (const path of paths) {
|
|
749
|
+
const value = getNested(input, path);
|
|
750
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
751
|
+
return value;
|
|
752
|
+
}
|
|
753
|
+
return void 0;
|
|
754
|
+
}
|
|
755
|
+
function inferOutcome(input) {
|
|
756
|
+
const exitCode = getNumber(input, ["exitCode", "exit_code", "status"]) ?? getNestedNumber(input, [["tool_response", "exitCode"], ["tool_response", "exit_code"], ["result", "exitCode"], ["result", "exit_code"]]);
|
|
757
|
+
if (typeof exitCode === "number")
|
|
758
|
+
return exitCode === 0 ? "success" : "failure";
|
|
759
|
+
const error2 = getString(input, ["error", "errorMessage"]) ?? getNestedString(input, [["tool_response", "error"], ["result", "error"]]);
|
|
760
|
+
if (error2)
|
|
761
|
+
return "failure";
|
|
762
|
+
return "unknown";
|
|
763
|
+
}
|
|
764
|
+
function outcomeForHook(hookName, input) {
|
|
765
|
+
if (hookName === "PostToolUseFailure") {
|
|
766
|
+
const interrupted = input["is_interrupt"] === true || getNested(input, ["tool_response", "interrupted"]) === true;
|
|
767
|
+
return interrupted ? "cancelled" : "failure";
|
|
768
|
+
}
|
|
769
|
+
if (hookName === "PostToolUse") {
|
|
770
|
+
if (getNested(input, ["tool_response", "interrupted"]) === true)
|
|
771
|
+
return "cancelled";
|
|
772
|
+
return "success";
|
|
773
|
+
}
|
|
774
|
+
return "unknown";
|
|
775
|
+
}
|
|
776
|
+
function looksLikeCorrection(text) {
|
|
777
|
+
if (!text)
|
|
778
|
+
return false;
|
|
779
|
+
return /\b(wrong|incorrect|try again|fix|not what i asked|that's not|that is not|redo|regenerate|you missed|doesn't work|does not work)\b/i.test(text);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
|
|
601
784
|
// ../packages/tool-kit/out/eventLog.js
|
|
602
785
|
var require_eventLog = __commonJS({
|
|
603
786
|
"../packages/tool-kit/out/eventLog.js"(exports) {
|
|
@@ -698,6 +881,7 @@ var require_http = __commonJS({
|
|
|
698
881
|
exports.postToolEvent = postToolEvent;
|
|
699
882
|
exports.postToolEventsBatch = postToolEventsBatch;
|
|
700
883
|
exports.parseIngestResponse = parseIngestResponse;
|
|
884
|
+
var tool_contract_1 = require_out();
|
|
701
885
|
var AscendaApiError = class extends Error {
|
|
702
886
|
status;
|
|
703
887
|
errorCode;
|
|
@@ -740,6 +924,35 @@ var require_http = __commonJS({
|
|
|
740
924
|
throw new AscendaApiError(response.status, void 0, await response.text());
|
|
741
925
|
return await response.json();
|
|
742
926
|
}
|
|
927
|
+
function isDeliveredStatus(value) {
|
|
928
|
+
return typeof value === "string" && tool_contract_1.TOOL_EVENT_DELIVERED_STATUSES.includes(value);
|
|
929
|
+
}
|
|
930
|
+
function readSuccessBody(body) {
|
|
931
|
+
let parsed;
|
|
932
|
+
try {
|
|
933
|
+
parsed = JSON.parse(body);
|
|
934
|
+
} catch {
|
|
935
|
+
return { duplicates: 0 };
|
|
936
|
+
}
|
|
937
|
+
if (!parsed || typeof parsed !== "object")
|
|
938
|
+
return { duplicates: 0 };
|
|
939
|
+
const single = parsed.status;
|
|
940
|
+
if (isDeliveredStatus(single))
|
|
941
|
+
return { duplicates: single === "duplicate" ? 1 : 0 };
|
|
942
|
+
const raw = parsed.results;
|
|
943
|
+
if (!Array.isArray(raw))
|
|
944
|
+
return { duplicates: 0 };
|
|
945
|
+
const results = [];
|
|
946
|
+
for (const item of raw) {
|
|
947
|
+
if (!item || typeof item !== "object")
|
|
948
|
+
continue;
|
|
949
|
+
const { index, status, reason } = item;
|
|
950
|
+
if (typeof index !== "number" || typeof status !== "string")
|
|
951
|
+
continue;
|
|
952
|
+
results.push({ index, status, ...typeof reason === "string" ? { reason } : {} });
|
|
953
|
+
}
|
|
954
|
+
return { duplicates: results.filter((item) => item.status === "duplicate").length, results };
|
|
955
|
+
}
|
|
743
956
|
function isRetryableStatus(status) {
|
|
744
957
|
return status === 408 || status === 429 || status !== void 0 && status >= 500 && status <= 599;
|
|
745
958
|
}
|
|
@@ -766,8 +979,20 @@ var require_http = __commonJS({
|
|
|
766
979
|
}
|
|
767
980
|
}
|
|
768
981
|
async function parseIngestResponse(response) {
|
|
769
|
-
if (response.ok)
|
|
770
|
-
|
|
982
|
+
if (response.ok) {
|
|
983
|
+
const outcome = { result: "accepted", httpStatus: response.status };
|
|
984
|
+
let read = { duplicates: 0 };
|
|
985
|
+
try {
|
|
986
|
+
read = readSuccessBody(await response.text());
|
|
987
|
+
} catch {
|
|
988
|
+
read = { duplicates: 0 };
|
|
989
|
+
}
|
|
990
|
+
return {
|
|
991
|
+
...outcome,
|
|
992
|
+
...read.duplicates > 0 ? { duplicates: read.duplicates } : {},
|
|
993
|
+
...read.results !== void 0 ? { results: read.results } : {}
|
|
994
|
+
};
|
|
995
|
+
}
|
|
771
996
|
const body = await response.text();
|
|
772
997
|
let errorCode;
|
|
773
998
|
try {
|
|
@@ -832,6 +1057,7 @@ var require_tokenStore = __commonJS({
|
|
|
832
1057
|
exports.ascendaHome = ascendaHome;
|
|
833
1058
|
exports.defaultTokenFilePath = defaultTokenFilePath2;
|
|
834
1059
|
exports.persistEventWriteToken = persistEventWriteToken2;
|
|
1060
|
+
exports.listPersistedToolInstallationIds = listPersistedToolInstallationIds;
|
|
835
1061
|
exports.readTokenFile = readTokenFile2;
|
|
836
1062
|
exports.sanitizeFilePart = sanitizeFilePart;
|
|
837
1063
|
var fs = __importStar(__require("fs"));
|
|
@@ -852,6 +1078,32 @@ var require_tokenStore = __commonJS({
|
|
|
852
1078
|
fs.chmodSync(tokenFilePath, 384);
|
|
853
1079
|
}
|
|
854
1080
|
}
|
|
1081
|
+
function listPersistedToolInstallationIds(toolType) {
|
|
1082
|
+
const prefix = `${sanitizeFilePart(toolType)}_`;
|
|
1083
|
+
const dir = path.join(ascendaHome(), "tokens");
|
|
1084
|
+
let names;
|
|
1085
|
+
try {
|
|
1086
|
+
names = fs.readdirSync(dir);
|
|
1087
|
+
} catch {
|
|
1088
|
+
return [];
|
|
1089
|
+
}
|
|
1090
|
+
const ids = [];
|
|
1091
|
+
for (const name of names.sort()) {
|
|
1092
|
+
if (!name.startsWith(prefix) || name.length === prefix.length)
|
|
1093
|
+
continue;
|
|
1094
|
+
const file = path.join(dir, name);
|
|
1095
|
+
try {
|
|
1096
|
+
if (!fs.statSync(file).isFile())
|
|
1097
|
+
continue;
|
|
1098
|
+
} catch {
|
|
1099
|
+
continue;
|
|
1100
|
+
}
|
|
1101
|
+
if (readTokenFile2(file) === void 0)
|
|
1102
|
+
continue;
|
|
1103
|
+
ids.push(`${toolType}:${name.slice(prefix.length)}`);
|
|
1104
|
+
}
|
|
1105
|
+
return ids;
|
|
1106
|
+
}
|
|
855
1107
|
function readTokenFile2(tokenFilePath) {
|
|
856
1108
|
try {
|
|
857
1109
|
if (!fs.existsSync(tokenFilePath))
|
|
@@ -911,8 +1163,11 @@ var require_stateStore = __commonJS({
|
|
|
911
1163
|
}();
|
|
912
1164
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
913
1165
|
exports.defaultStateFilePath = defaultStateFilePath;
|
|
1166
|
+
exports.unresolvedToolInstallationId = unresolvedToolInstallationId;
|
|
1167
|
+
exports.unresolvedStateFilePath = unresolvedStateFilePath;
|
|
914
1168
|
exports.readCollectorState = readCollectorState;
|
|
915
1169
|
exports.recordSendOutcome = recordSendOutcome;
|
|
1170
|
+
exports.recordOutboxDiscard = recordOutboxDiscard;
|
|
916
1171
|
exports.shouldAnnounceFailure = shouldAnnounceFailure;
|
|
917
1172
|
exports.markFailureNotified = markFailureNotified;
|
|
918
1173
|
var fs = __importStar(__require("fs"));
|
|
@@ -924,6 +1179,12 @@ var require_stateStore = __commonJS({
|
|
|
924
1179
|
const base = dir ? dir : path.join(os.homedir(), ".ascenda", "state");
|
|
925
1180
|
return path.join(base, `${(0, tokenStore_1.sanitizeFilePart)(toolInstallationId)}.json`);
|
|
926
1181
|
}
|
|
1182
|
+
function unresolvedToolInstallationId(toolType) {
|
|
1183
|
+
return `${toolType}:unresolved`;
|
|
1184
|
+
}
|
|
1185
|
+
function unresolvedStateFilePath(toolType) {
|
|
1186
|
+
return defaultStateFilePath(unresolvedToolInstallationId(toolType));
|
|
1187
|
+
}
|
|
927
1188
|
function readCollectorState(stateFilePath) {
|
|
928
1189
|
try {
|
|
929
1190
|
if (!fs.existsSync(stateFilePath))
|
|
@@ -956,7 +1217,28 @@ var require_stateStore = __commonJS({
|
|
|
956
1217
|
// the one already open. Carrying `notifiedFailingSince` across a
|
|
957
1218
|
// continuing episode is what keeps the notice to once per outage.
|
|
958
1219
|
...accepted ? {} : { failingSince: previous?.failingSince ?? now },
|
|
959
|
-
...accepted ? {} : previous?.notifiedFailingSince !== void 0 ? { notifiedFailingSince: previous.notifiedFailingSince } : {}
|
|
1220
|
+
...accepted ? {} : previous?.notifiedFailingSince !== void 0 ? { notifiedFailingSince: previous.notifiedFailingSince } : {},
|
|
1221
|
+
// Cumulative by design: a send outcome, success included, never erases
|
|
1222
|
+
// the record of what the outbox had to throw away.
|
|
1223
|
+
...previous?.outboxDiscarded !== void 0 ? { outboxDiscarded: previous.outboxDiscarded } : {}
|
|
1224
|
+
};
|
|
1225
|
+
writeStateFile(stateFilePath, next);
|
|
1226
|
+
return next;
|
|
1227
|
+
}
|
|
1228
|
+
function recordOutboxDiscard(stateFilePath, toolInstallationId, discard) {
|
|
1229
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1230
|
+
const previous = readCollectorState(stateFilePath);
|
|
1231
|
+
const next = {
|
|
1232
|
+
...previous ?? { lastAttemptAt: now, consecutiveFailures: 0 },
|
|
1233
|
+
toolInstallationId,
|
|
1234
|
+
lastOutcome: "outbox_discarded",
|
|
1235
|
+
outboxDiscarded: {
|
|
1236
|
+
total: (previous?.outboxDiscarded?.total ?? 0) + discard.count,
|
|
1237
|
+
lastAt: now,
|
|
1238
|
+
lastCount: discard.count,
|
|
1239
|
+
lastReasons: discard.reasons,
|
|
1240
|
+
...discard.oldestQueuedAt !== void 0 ? { lastOldestQueuedAt: discard.oldestQueuedAt } : {}
|
|
1241
|
+
}
|
|
960
1242
|
};
|
|
961
1243
|
writeStateFile(stateFilePath, next);
|
|
962
1244
|
return next;
|
|
@@ -996,19 +1278,241 @@ var require_stateStore = __commonJS({
|
|
|
996
1278
|
}
|
|
997
1279
|
});
|
|
998
1280
|
|
|
999
|
-
// ../packages/tool-kit/out/
|
|
1000
|
-
var
|
|
1001
|
-
"../packages/tool-kit/out/
|
|
1281
|
+
// ../packages/tool-kit/out/outbox.js
|
|
1282
|
+
var require_outbox = __commonJS({
|
|
1283
|
+
"../packages/tool-kit/out/outbox.js"(exports) {
|
|
1002
1284
|
"use strict";
|
|
1003
|
-
Object.
|
|
1004
|
-
|
|
1005
|
-
|
|
1285
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
1286
|
+
if (k2 === void 0) k2 = k;
|
|
1287
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1288
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1289
|
+
desc = { enumerable: true, get: function() {
|
|
1290
|
+
return m[k];
|
|
1291
|
+
} };
|
|
1292
|
+
}
|
|
1293
|
+
Object.defineProperty(o, k2, desc);
|
|
1294
|
+
} : function(o, m, k, k2) {
|
|
1295
|
+
if (k2 === void 0) k2 = k;
|
|
1296
|
+
o[k2] = m[k];
|
|
1297
|
+
});
|
|
1298
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
1299
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1300
|
+
} : function(o, v) {
|
|
1301
|
+
o["default"] = v;
|
|
1302
|
+
});
|
|
1303
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
1304
|
+
var ownKeys = function(o) {
|
|
1305
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
1306
|
+
var ar = [];
|
|
1307
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
1308
|
+
return ar;
|
|
1309
|
+
};
|
|
1310
|
+
return ownKeys(o);
|
|
1311
|
+
};
|
|
1312
|
+
return function(mod) {
|
|
1313
|
+
if (mod && mod.__esModule) return mod;
|
|
1314
|
+
var result = {};
|
|
1315
|
+
if (mod != null) {
|
|
1316
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
1317
|
+
}
|
|
1318
|
+
__setModuleDefault(result, mod);
|
|
1319
|
+
return result;
|
|
1320
|
+
};
|
|
1321
|
+
}();
|
|
1322
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1323
|
+
exports.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE = exports.DEFAULT_OUTBOX_MAX_AGE_MS = exports.DEFAULT_OUTBOX_MAX_ENTRIES = exports.OUTBOX_DRAIN_ENV_VAR = void 0;
|
|
1324
|
+
exports.outboxDrainEnabled = outboxDrainEnabled;
|
|
1325
|
+
exports.defaultOutboxFilePath = defaultOutboxFilePath;
|
|
1326
|
+
exports.appendToOutbox = appendToOutbox;
|
|
1327
|
+
exports.readOutboxSummary = readOutboxSummary;
|
|
1328
|
+
exports.claimOutbox = claimOutbox;
|
|
1329
|
+
exports.enforceOutboxBounds = enforceOutboxBounds;
|
|
1330
|
+
var fs = __importStar(__require("fs"));
|
|
1331
|
+
var path = __importStar(__require("path"));
|
|
1332
|
+
var stateStore_1 = require_stateStore();
|
|
1333
|
+
var tokenStore_1 = require_tokenStore();
|
|
1334
|
+
exports.OUTBOX_DRAIN_ENV_VAR = "ASCENDA_OUTBOX_DRAIN";
|
|
1335
|
+
exports.DEFAULT_OUTBOX_MAX_ENTRIES = 1e4;
|
|
1336
|
+
exports.DEFAULT_OUTBOX_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
1337
|
+
exports.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE = 100;
|
|
1338
|
+
var ORPHANED_CLAIM_AGE_MS = 6e4;
|
|
1339
|
+
var CLAIM_SUFFIX = ".draining";
|
|
1340
|
+
function outboxDrainEnabled(env = process.env) {
|
|
1341
|
+
const value = env[exports.OUTBOX_DRAIN_ENV_VAR]?.trim().toLowerCase();
|
|
1342
|
+
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
1343
|
+
}
|
|
1344
|
+
function defaultOutboxFilePath(toolInstallationId) {
|
|
1345
|
+
const dir = path.dirname((0, stateStore_1.defaultStateFilePath)(toolInstallationId));
|
|
1346
|
+
return path.join(dir, `${(0, tokenStore_1.sanitizeFilePart)(toolInstallationId)}.outbox.jsonl`);
|
|
1347
|
+
}
|
|
1348
|
+
function appendToOutbox(outboxFilePath, payload, now = /* @__PURE__ */ new Date()) {
|
|
1349
|
+
try {
|
|
1350
|
+
const dir = path.dirname(outboxFilePath);
|
|
1351
|
+
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
1352
|
+
const entry = { queuedAt: now.toISOString(), payload };
|
|
1353
|
+
fs.appendFileSync(outboxFilePath, `${JSON.stringify(entry)}
|
|
1354
|
+
`, { encoding: "utf8", mode: 384 });
|
|
1355
|
+
if (process.platform !== "win32")
|
|
1356
|
+
fs.chmodSync(outboxFilePath, 384);
|
|
1357
|
+
return true;
|
|
1358
|
+
} catch {
|
|
1359
|
+
return false;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
function readOutboxSummary(outboxFilePath) {
|
|
1363
|
+
const files = [outboxFilePath, ...listClaimFiles(outboxFilePath)].filter((file) => fs.existsSync(file));
|
|
1364
|
+
if (files.length === 0)
|
|
1365
|
+
return void 0;
|
|
1366
|
+
let depth = 0;
|
|
1367
|
+
let unreadableLines = 0;
|
|
1368
|
+
let oldestQueuedAt;
|
|
1369
|
+
for (const file of files) {
|
|
1370
|
+
const { entries, unreadable } = readEntries(file);
|
|
1371
|
+
depth += entries.length;
|
|
1372
|
+
unreadableLines += unreadable;
|
|
1373
|
+
for (const entry of entries) {
|
|
1374
|
+
if (oldestQueuedAt === void 0 || entry.queuedAt < oldestQueuedAt)
|
|
1375
|
+
oldestQueuedAt = entry.queuedAt;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return { depth, unreadableLines, ...oldestQueuedAt !== void 0 ? { oldestQueuedAt } : {} };
|
|
1379
|
+
}
|
|
1380
|
+
function claimOutbox(outboxFilePath, now = Date.now()) {
|
|
1381
|
+
const claimPath = `${outboxFilePath}.${process.pid}${CLAIM_SUFFIX}`;
|
|
1382
|
+
const claimed = [];
|
|
1383
|
+
try {
|
|
1384
|
+
fs.renameSync(outboxFilePath, claimPath);
|
|
1385
|
+
claimed.push(claimPath);
|
|
1386
|
+
} catch {
|
|
1387
|
+
}
|
|
1388
|
+
let orphanIndex = 0;
|
|
1389
|
+
for (const orphan of listClaimFiles(outboxFilePath)) {
|
|
1390
|
+
if (claimed.includes(orphan))
|
|
1391
|
+
continue;
|
|
1392
|
+
try {
|
|
1393
|
+
if (now - fs.statSync(orphan).mtimeMs < ORPHANED_CLAIM_AGE_MS)
|
|
1394
|
+
continue;
|
|
1395
|
+
const mine = `${claimPath}.${orphanIndex++}`;
|
|
1396
|
+
fs.renameSync(orphan, mine);
|
|
1397
|
+
claimed.push(mine);
|
|
1398
|
+
} catch {
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
if (claimed.length === 0)
|
|
1402
|
+
return void 0;
|
|
1403
|
+
const entries = [];
|
|
1404
|
+
let unreadable = 0;
|
|
1405
|
+
for (const file of claimed) {
|
|
1406
|
+
const read = readEntries(file);
|
|
1407
|
+
entries.push(...read.entries);
|
|
1408
|
+
unreadable += read.unreadable;
|
|
1409
|
+
}
|
|
1410
|
+
entries.sort((a, b) => a.queuedAt < b.queuedAt ? -1 : a.queuedAt > b.queuedAt ? 1 : 0);
|
|
1411
|
+
let released = false;
|
|
1412
|
+
return {
|
|
1413
|
+
entries,
|
|
1414
|
+
unreadable,
|
|
1415
|
+
release(remainder) {
|
|
1416
|
+
if (released)
|
|
1417
|
+
return;
|
|
1418
|
+
released = true;
|
|
1419
|
+
if (remainder.length > 0) {
|
|
1420
|
+
try {
|
|
1421
|
+
fs.mkdirSync(path.dirname(outboxFilePath), { recursive: true, mode: 448 });
|
|
1422
|
+
fs.appendFileSync(outboxFilePath, remainder.map((entry) => `${JSON.stringify(entry)}
|
|
1423
|
+
`).join(""), { encoding: "utf8", mode: 384 });
|
|
1424
|
+
if (process.platform !== "win32")
|
|
1425
|
+
fs.chmodSync(outboxFilePath, 384);
|
|
1426
|
+
} catch {
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
for (const file of claimed) {
|
|
1431
|
+
try {
|
|
1432
|
+
fs.unlinkSync(file);
|
|
1433
|
+
} catch {
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
function enforceOutboxBounds(entries, bounds, now = Date.now()) {
|
|
1440
|
+
const reasons = {};
|
|
1441
|
+
let oldestQueuedAt;
|
|
1442
|
+
const cutoff = new Date(now - bounds.maxAgeMs).toISOString();
|
|
1443
|
+
const fresh = [];
|
|
1444
|
+
for (const entry of entries) {
|
|
1445
|
+
if (entry.queuedAt < cutoff) {
|
|
1446
|
+
reasons.age = (reasons.age ?? 0) + 1;
|
|
1447
|
+
if (oldestQueuedAt === void 0 || entry.queuedAt < oldestQueuedAt)
|
|
1448
|
+
oldestQueuedAt = entry.queuedAt;
|
|
1449
|
+
} else {
|
|
1450
|
+
fresh.push(entry);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
const excess = Math.max(0, fresh.length - bounds.maxEntries);
|
|
1454
|
+
if (excess > 0) {
|
|
1455
|
+
reasons.count = excess;
|
|
1456
|
+
const first = fresh[0]?.queuedAt;
|
|
1457
|
+
if (first !== void 0 && (oldestQueuedAt === void 0 || first < oldestQueuedAt))
|
|
1458
|
+
oldestQueuedAt = first;
|
|
1459
|
+
}
|
|
1460
|
+
const kept = excess > 0 ? fresh.slice(excess) : fresh;
|
|
1461
|
+
const count = Object.values(reasons).reduce((sum, n) => sum + (n ?? 0), 0);
|
|
1462
|
+
return { kept, discarded: { count, reasons, ...oldestQueuedAt !== void 0 ? { oldestQueuedAt } : {} } };
|
|
1463
|
+
}
|
|
1464
|
+
function listClaimFiles(outboxFilePath) {
|
|
1465
|
+
const dir = path.dirname(outboxFilePath);
|
|
1466
|
+
const prefix = `${path.basename(outboxFilePath)}.`;
|
|
1467
|
+
try {
|
|
1468
|
+
return fs.readdirSync(dir).filter((name) => name.startsWith(prefix) && name.includes(CLAIM_SUFFIX)).map((name) => path.join(dir, name)).sort();
|
|
1469
|
+
} catch {
|
|
1470
|
+
return [];
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
function readEntries(file) {
|
|
1474
|
+
let raw;
|
|
1475
|
+
try {
|
|
1476
|
+
raw = fs.readFileSync(file, "utf8");
|
|
1477
|
+
} catch {
|
|
1478
|
+
return { entries: [], unreadable: 0 };
|
|
1479
|
+
}
|
|
1480
|
+
const entries = [];
|
|
1481
|
+
let unreadable = 0;
|
|
1482
|
+
for (const line of raw.split("\n")) {
|
|
1483
|
+
if (!line.trim())
|
|
1484
|
+
continue;
|
|
1485
|
+
try {
|
|
1486
|
+
const parsed = JSON.parse(line);
|
|
1487
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.queuedAt !== "string" || !parsed.payload || typeof parsed.payload !== "object") {
|
|
1488
|
+
unreadable += 1;
|
|
1489
|
+
continue;
|
|
1490
|
+
}
|
|
1491
|
+
entries.push({ queuedAt: parsed.queuedAt, payload: parsed.payload });
|
|
1492
|
+
} catch {
|
|
1493
|
+
unreadable += 1;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
return { entries, unreadable };
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
// ../packages/tool-kit/out/eventSender.js
|
|
1502
|
+
var require_eventSender = __commonJS({
|
|
1503
|
+
"../packages/tool-kit/out/eventSender.js"(exports) {
|
|
1504
|
+
"use strict";
|
|
1505
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1506
|
+
exports.AscendaEventSender = exports.AscendaSemanticEventError = void 0;
|
|
1507
|
+
exports.buildEventPayload = buildEventPayload;
|
|
1006
1508
|
var afterHours_1 = require_afterHours();
|
|
1007
1509
|
var tool_contract_1 = require_out();
|
|
1008
1510
|
var eventLog_1 = require_eventLog();
|
|
1009
1511
|
var http_1 = require_http();
|
|
1512
|
+
var outbox_1 = require_outbox();
|
|
1010
1513
|
var tokenStore_1 = require_tokenStore();
|
|
1011
1514
|
var stateStore_1 = require_stateStore();
|
|
1515
|
+
var payload_1 = require_payload();
|
|
1012
1516
|
var AscendaSemanticEventError = class extends Error {
|
|
1013
1517
|
constructor(message) {
|
|
1014
1518
|
super(message);
|
|
@@ -1021,6 +1525,7 @@ var require_eventSender = __commonJS({
|
|
|
1021
1525
|
toolInstallationId: identity.toolInstallationId,
|
|
1022
1526
|
source: identity.source,
|
|
1023
1527
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1528
|
+
idempotencyKey: (0, payload_1.mintIdempotencyKey)(),
|
|
1024
1529
|
utcOffsetMinutes: (0, afterHours_1.utcOffsetMinutesAt)(/* @__PURE__ */ new Date()),
|
|
1025
1530
|
sessionId: identity.sessionId ?? void 0,
|
|
1026
1531
|
workspaceHash: identity.workspaceHash ?? void 0,
|
|
@@ -1038,6 +1543,9 @@ var require_eventSender = __commonJS({
|
|
|
1038
1543
|
config;
|
|
1039
1544
|
eventWriteToken;
|
|
1040
1545
|
lastState;
|
|
1546
|
+
lastDrain;
|
|
1547
|
+
/** One outbox pass per sender, i.e. per hook process. The hook is on the user's critical path. */
|
|
1548
|
+
outboxServiced = false;
|
|
1041
1549
|
constructor(config2) {
|
|
1042
1550
|
this.config = config2;
|
|
1043
1551
|
this.eventWriteToken = config2.eventWriteToken;
|
|
@@ -1076,6 +1584,7 @@ var require_eventSender = __commonJS({
|
|
|
1076
1584
|
source: this.config.source,
|
|
1077
1585
|
eventType: mapped.eventType,
|
|
1078
1586
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1587
|
+
idempotencyKey: (0, payload_1.mintIdempotencyKey)(),
|
|
1079
1588
|
utcOffsetMinutes: (0, afterHours_1.utcOffsetMinutesAt)(/* @__PURE__ */ new Date()),
|
|
1080
1589
|
severity: "low",
|
|
1081
1590
|
sessionId: this.config.sessionId ?? void 0,
|
|
@@ -1106,6 +1615,7 @@ var require_eventSender = __commonJS({
|
|
|
1106
1615
|
source: this.config.source,
|
|
1107
1616
|
eventType: mapped.eventType,
|
|
1108
1617
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1618
|
+
idempotencyKey: (0, payload_1.mintIdempotencyKey)(),
|
|
1109
1619
|
utcOffsetMinutes: (0, afterHours_1.utcOffsetMinutesAt)(/* @__PURE__ */ new Date()),
|
|
1110
1620
|
severity: "low",
|
|
1111
1621
|
sessionId: this.config.sessionId ?? void 0,
|
|
@@ -1124,15 +1634,30 @@ var require_eventSender = __commonJS({
|
|
|
1124
1634
|
* deliberate: Claude Code, Codex, the GitHub collector and the MCP server all
|
|
1125
1635
|
* send through this method, and the defect being fixed showed up in three
|
|
1126
1636
|
* separate components because each was left to notice its own failures.
|
|
1637
|
+
*
|
|
1638
|
+
* The outbox is serviced first, once per process. If that pass just watched
|
|
1639
|
+
* the ingest door refuse a batch, the live event is not offered to the same
|
|
1640
|
+
* door a second time in the same instant: it inherits the pass's outcome,
|
|
1641
|
+
* and a retryable one puts it straight in the queue. That is what keeps a
|
|
1642
|
+
* hook during an outage to one bounded round trip instead of three.
|
|
1127
1643
|
*/
|
|
1128
1644
|
async post(payload) {
|
|
1129
|
-
const
|
|
1645
|
+
const halted = await this.serviceOutbox();
|
|
1646
|
+
let outcome;
|
|
1647
|
+
let queued = false;
|
|
1648
|
+
if (halted) {
|
|
1649
|
+
outcome = halted;
|
|
1650
|
+
queued = this.isRetryable(outcome) && this.enqueue(payload);
|
|
1651
|
+
} else {
|
|
1652
|
+
outcome = await this.attempt(payload);
|
|
1653
|
+
queued = this.isRetryable(outcome) && this.enqueue(payload);
|
|
1654
|
+
}
|
|
1130
1655
|
this.lastState = (0, stateStore_1.recordSendOutcome)(this.stateFilePath(), this.config.toolInstallationId, outcome.result, {
|
|
1131
1656
|
httpStatus: outcome.httpStatus,
|
|
1132
1657
|
errorCode: outcome.errorCode,
|
|
1133
|
-
detail: outcome.detail
|
|
1658
|
+
detail: queued ? withNote(outcome.detail, "queued in outbox") : outcome.detail
|
|
1134
1659
|
});
|
|
1135
|
-
this.log(payload, outcome.result);
|
|
1660
|
+
this.log(payload, outcome.result, queued ? "queued" : void 0);
|
|
1136
1661
|
return outcome.result;
|
|
1137
1662
|
}
|
|
1138
1663
|
/**
|
|
@@ -1141,6 +1666,15 @@ var require_eventSender = __commonJS({
|
|
|
1141
1666
|
* error gets one retry, because the common cases (a restarting instance, a
|
|
1142
1667
|
* proxy blip, a 429) clear in well under a second and the alternative is
|
|
1143
1668
|
* losing the event outright.
|
|
1669
|
+
*
|
|
1670
|
+
* Both recoveries resend the same `payload` object, so the `idempotencyKey`
|
|
1671
|
+
* minted at construction is what the server sees on every attempt. That is
|
|
1672
|
+
* what lets a retry of a request the server actually processed (a timeout
|
|
1673
|
+
* after the write, a 502 from a proxy in front of a 200) come back
|
|
1674
|
+
* `duplicate` instead of landing twice. Never rebuild the payload here.
|
|
1675
|
+
*
|
|
1676
|
+
* When the retry fails too, the caller queues the payload: anything longer
|
|
1677
|
+
* than the pause here is the outbox's job, not another in-process wait.
|
|
1144
1678
|
*/
|
|
1145
1679
|
async attempt(payload) {
|
|
1146
1680
|
const outcome = await (0, http_1.postToolEvent)(this.config.apiBaseUrl, this.eventWriteToken, payload, this.signal());
|
|
@@ -1149,12 +1683,138 @@ var require_eventSender = __commonJS({
|
|
|
1149
1683
|
return outcome;
|
|
1150
1684
|
return (0, http_1.postToolEvent)(this.config.apiBaseUrl, this.eventWriteToken, payload, this.signal());
|
|
1151
1685
|
}
|
|
1152
|
-
if (
|
|
1686
|
+
if (this.isRetryable(outcome)) {
|
|
1153
1687
|
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));
|
|
1154
1688
|
return (0, http_1.postToolEvent)(this.config.apiBaseUrl, this.eventWriteToken, payload, this.signal());
|
|
1155
1689
|
}
|
|
1156
1690
|
return outcome;
|
|
1157
1691
|
}
|
|
1692
|
+
/** A failure that never reached a verdict. Replaying can change the answer. */
|
|
1693
|
+
isRetryable(outcome) {
|
|
1694
|
+
return outcome.result === "transport_error" && (outcome.httpStatus === void 0 || (0, http_1.isRetryableStatus)(outcome.httpStatus));
|
|
1695
|
+
}
|
|
1696
|
+
/**
|
|
1697
|
+
* Keeps a refused payload for a later drain. Returns whether it is now on
|
|
1698
|
+
* disk; when it is not (read-only home, full disk) the event is lost and the
|
|
1699
|
+
* journal's detail says so instead of implying it was kept.
|
|
1700
|
+
*/
|
|
1701
|
+
enqueue(payload) {
|
|
1702
|
+
return (0, outbox_1.appendToOutbox)(this.outboxFilePath(), payload);
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* One pass over the outbox: claim it, apply the bounds, and — when sending
|
|
1706
|
+
* is enabled — offer one batch, oldest first, to the batch door.
|
|
1707
|
+
*
|
|
1708
|
+
* Entries are deleted on `accepted` or `duplicate`, decided on `status`
|
|
1709
|
+
* alone; `reason` is for a person reading their logs. A per-item `rejected`
|
|
1710
|
+
* is a verdict, and replaying a verdict cannot change it, so those are
|
|
1711
|
+
* discarded and journaled rather than kept forever. A whole-batch
|
|
1712
|
+
* `validation_failed` is the same verdict for every item. Anything else
|
|
1713
|
+
* stops the pass with everything still on disk, and is returned so the live
|
|
1714
|
+
* send can skip a door that just refused.
|
|
1715
|
+
*
|
|
1716
|
+
* Never loops, never backs off, never sends more than one batch: the next
|
|
1717
|
+
* hook invocation is usually seconds away, and a hook sitting in a retry
|
|
1718
|
+
* loop delays the tool call the user is waiting on.
|
|
1719
|
+
*/
|
|
1720
|
+
async serviceOutbox() {
|
|
1721
|
+
if (this.outboxServiced)
|
|
1722
|
+
return void 0;
|
|
1723
|
+
this.outboxServiced = true;
|
|
1724
|
+
const sendEnabled = this.config.outboxDrain ?? (0, outbox_1.outboxDrainEnabled)();
|
|
1725
|
+
const claimed = (0, outbox_1.claimOutbox)(this.outboxFilePath());
|
|
1726
|
+
if (!claimed) {
|
|
1727
|
+
this.lastDrain = { found: 0, discarded: 0, delivered: 0, remaining: 0, sendEnabled };
|
|
1728
|
+
return void 0;
|
|
1729
|
+
}
|
|
1730
|
+
const found = claimed.entries.length + claimed.unreadable;
|
|
1731
|
+
const { kept, discarded } = (0, outbox_1.enforceOutboxBounds)(claimed.entries, {
|
|
1732
|
+
maxEntries: this.config.outboxMaxEntries ?? outbox_1.DEFAULT_OUTBOX_MAX_ENTRIES,
|
|
1733
|
+
maxAgeMs: this.config.outboxMaxAgeMs ?? outbox_1.DEFAULT_OUTBOX_MAX_AGE_MS
|
|
1734
|
+
});
|
|
1735
|
+
if (claimed.unreadable > 0) {
|
|
1736
|
+
discarded.count += claimed.unreadable;
|
|
1737
|
+
discarded.reasons.unreadable = claimed.unreadable;
|
|
1738
|
+
}
|
|
1739
|
+
let discardedTotal = this.journalDiscard(discarded);
|
|
1740
|
+
if (!sendEnabled || kept.length === 0) {
|
|
1741
|
+
claimed.release(kept);
|
|
1742
|
+
this.lastDrain = { found, discarded: discardedTotal, delivered: 0, remaining: kept.length, sendEnabled };
|
|
1743
|
+
return void 0;
|
|
1744
|
+
}
|
|
1745
|
+
const batchSize = this.config.outboxDrainBatchSize ?? outbox_1.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE;
|
|
1746
|
+
const batch = kept.slice(0, batchSize);
|
|
1747
|
+
const rest = kept.slice(batchSize);
|
|
1748
|
+
const outcome = await this.attemptBatch(batch.map((entry) => entry.payload));
|
|
1749
|
+
let delivered = [];
|
|
1750
|
+
let rejected = [];
|
|
1751
|
+
let undecided = [];
|
|
1752
|
+
let halted;
|
|
1753
|
+
if (outcome.result === "accepted") {
|
|
1754
|
+
if (outcome.results === void 0) {
|
|
1755
|
+
delivered = batch;
|
|
1756
|
+
} else {
|
|
1757
|
+
const byIndex = new Map(outcome.results.map((item) => [item.index, item.status]));
|
|
1758
|
+
for (const [index, entry] of batch.entries()) {
|
|
1759
|
+
const status = byIndex.get(index);
|
|
1760
|
+
if (status !== void 0 && tool_contract_1.TOOL_EVENT_DELIVERED_STATUSES.includes(status))
|
|
1761
|
+
delivered.push(entry);
|
|
1762
|
+
else if (status === "rejected")
|
|
1763
|
+
rejected.push(entry);
|
|
1764
|
+
else
|
|
1765
|
+
undecided.push(entry);
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
} else if (outcome.result === "validation_failed") {
|
|
1769
|
+
rejected = batch;
|
|
1770
|
+
} else {
|
|
1771
|
+
undecided = batch;
|
|
1772
|
+
halted = outcome;
|
|
1773
|
+
}
|
|
1774
|
+
if (rejected.length > 0) {
|
|
1775
|
+
discardedTotal += this.journalDiscard({ count: rejected.length, reasons: { rejected: rejected.length }, oldestQueuedAt: rejected[0]?.queuedAt });
|
|
1776
|
+
}
|
|
1777
|
+
if (!halted) {
|
|
1778
|
+
this.lastState = (0, stateStore_1.recordSendOutcome)(this.stateFilePath(), this.config.toolInstallationId, outcome.result, {
|
|
1779
|
+
httpStatus: outcome.httpStatus,
|
|
1780
|
+
errorCode: outcome.errorCode,
|
|
1781
|
+
detail: withNote(outcome.detail, `outbox drain: ${delivered.length} delivered`)
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
for (const entry of delivered)
|
|
1785
|
+
this.log(entry.payload, "accepted", "drained");
|
|
1786
|
+
const remainder = [...undecided, ...rest];
|
|
1787
|
+
claimed.release(remainder);
|
|
1788
|
+
this.lastDrain = {
|
|
1789
|
+
found,
|
|
1790
|
+
discarded: discardedTotal,
|
|
1791
|
+
delivered: delivered.length,
|
|
1792
|
+
remaining: remainder.length,
|
|
1793
|
+
sendEnabled,
|
|
1794
|
+
...halted ? { halted: halted.result } : {}
|
|
1795
|
+
};
|
|
1796
|
+
return halted;
|
|
1797
|
+
}
|
|
1798
|
+
/** The batch door, with the same single token renewal as the live path and no in-process retry. */
|
|
1799
|
+
async attemptBatch(payloads) {
|
|
1800
|
+
const outcome = await (0, http_1.postToolEventsBatch)(this.config.apiBaseUrl, this.eventWriteToken, payloads, this.signal());
|
|
1801
|
+
if (outcome.result !== "auth_failed")
|
|
1802
|
+
return outcome;
|
|
1803
|
+
if (!await this.renewEventToken())
|
|
1804
|
+
return outcome;
|
|
1805
|
+
return (0, http_1.postToolEventsBatch)(this.config.apiBaseUrl, this.eventWriteToken, payloads, this.signal());
|
|
1806
|
+
}
|
|
1807
|
+
journalDiscard(discard) {
|
|
1808
|
+
if (discard.count === 0)
|
|
1809
|
+
return 0;
|
|
1810
|
+
const reasons = discard.reasons;
|
|
1811
|
+
this.lastState = (0, stateStore_1.recordOutboxDiscard)(this.stateFilePath(), this.config.toolInstallationId, {
|
|
1812
|
+
count: discard.count,
|
|
1813
|
+
reasons,
|
|
1814
|
+
oldestQueuedAt: discard.oldestQueuedAt
|
|
1815
|
+
});
|
|
1816
|
+
return discard.count;
|
|
1817
|
+
}
|
|
1158
1818
|
/**
|
|
1159
1819
|
* The state written by the most recent send, so a caller can decide whether
|
|
1160
1820
|
* to surface a one-time notice without re-reading the journal it just wrote.
|
|
@@ -1162,10 +1822,16 @@ var require_eventSender = __commonJS({
|
|
|
1162
1822
|
get state() {
|
|
1163
1823
|
return this.lastState;
|
|
1164
1824
|
}
|
|
1825
|
+
/** What this sender's one outbox pass did; undefined before the first send. */
|
|
1826
|
+
get drain() {
|
|
1827
|
+
return this.lastDrain;
|
|
1828
|
+
}
|
|
1165
1829
|
stateFilePath() {
|
|
1166
1830
|
return this.config.stateFilePath ?? (0, stateStore_1.defaultStateFilePath)(this.config.toolInstallationId);
|
|
1167
1831
|
}
|
|
1168
|
-
|
|
1832
|
+
outboxFilePath() {
|
|
1833
|
+
return this.config.outboxFilePath ?? (0, outbox_1.defaultOutboxFilePath)(this.config.toolInstallationId);
|
|
1834
|
+
}
|
|
1169
1835
|
/**
|
|
1170
1836
|
* Every send path funnels through {@link post}, so semantic and
|
|
1171
1837
|
* collaboration signals are logged on the same terms as host events — the
|
|
@@ -1175,12 +1841,13 @@ var require_eventSender = __commonJS({
|
|
|
1175
1841
|
* It is now `transport_error` through the ordinary path, because the
|
|
1176
1842
|
* transport returns that outcome instead of throwing.
|
|
1177
1843
|
*/
|
|
1178
|
-
log(payload, delivery) {
|
|
1844
|
+
log(payload, delivery, outbox) {
|
|
1179
1845
|
const logFile = this.config.eventLogFile === void 0 ? (0, eventLog_1.resolveEventLogPath)() : this.config.eventLogFile;
|
|
1180
1846
|
if (!logFile)
|
|
1181
1847
|
return;
|
|
1182
|
-
(0, eventLog_1.appendEventLog)(logFile, { loggedAt: (/* @__PURE__ */ new Date()).toISOString(), delivery, payload });
|
|
1848
|
+
(0, eventLog_1.appendEventLog)(logFile, { loggedAt: (/* @__PURE__ */ new Date()).toISOString(), delivery, payload, ...outbox ? { outbox } : {} });
|
|
1183
1849
|
}
|
|
1850
|
+
/** Never throws: a renewal that errors is a failed renewal, not a failed turn. */
|
|
1184
1851
|
async renewEventToken() {
|
|
1185
1852
|
try {
|
|
1186
1853
|
const renewed = await (0, http_1.renewToolToken)(this.config.apiBaseUrl, this.eventWriteToken, this.signal());
|
|
@@ -1198,6 +1865,9 @@ var require_eventSender = __commonJS({
|
|
|
1198
1865
|
}
|
|
1199
1866
|
};
|
|
1200
1867
|
exports.AscendaEventSender = AscendaEventSender2;
|
|
1868
|
+
function withNote(detail, note) {
|
|
1869
|
+
return detail ? `${detail} (${note})` : note;
|
|
1870
|
+
}
|
|
1201
1871
|
}
|
|
1202
1872
|
});
|
|
1203
1873
|
|
|
@@ -1345,6 +2015,269 @@ var require_contextRegistry = __commonJS({
|
|
|
1345
2015
|
}
|
|
1346
2016
|
});
|
|
1347
2017
|
|
|
2018
|
+
// ../packages/tool-kit/out/credentials.js
|
|
2019
|
+
var require_credentials = __commonJS({
|
|
2020
|
+
"../packages/tool-kit/out/credentials.js"(exports) {
|
|
2021
|
+
"use strict";
|
|
2022
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2023
|
+
if (k2 === void 0) k2 = k;
|
|
2024
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2025
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2026
|
+
desc = { enumerable: true, get: function() {
|
|
2027
|
+
return m[k];
|
|
2028
|
+
} };
|
|
2029
|
+
}
|
|
2030
|
+
Object.defineProperty(o, k2, desc);
|
|
2031
|
+
} : function(o, m, k, k2) {
|
|
2032
|
+
if (k2 === void 0) k2 = k;
|
|
2033
|
+
o[k2] = m[k];
|
|
2034
|
+
});
|
|
2035
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
2036
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
2037
|
+
} : function(o, v) {
|
|
2038
|
+
o["default"] = v;
|
|
2039
|
+
});
|
|
2040
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
2041
|
+
var ownKeys = function(o) {
|
|
2042
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
2043
|
+
var ar = [];
|
|
2044
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
2045
|
+
return ar;
|
|
2046
|
+
};
|
|
2047
|
+
return ownKeys(o);
|
|
2048
|
+
};
|
|
2049
|
+
return function(mod) {
|
|
2050
|
+
if (mod && mod.__esModule) return mod;
|
|
2051
|
+
var result = {};
|
|
2052
|
+
if (mod != null) {
|
|
2053
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
2054
|
+
}
|
|
2055
|
+
__setModuleDefault(result, mod);
|
|
2056
|
+
return result;
|
|
2057
|
+
};
|
|
2058
|
+
}();
|
|
2059
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2060
|
+
exports.credentialsFilePath = credentialsFilePath;
|
|
2061
|
+
exports.readMachineCredentials = readMachineCredentials;
|
|
2062
|
+
exports.writeMachineCredentials = writeMachineCredentials;
|
|
2063
|
+
exports.writeTopLevelCredentials = writeTopLevelCredentials;
|
|
2064
|
+
exports.readHostCredentials = readHostCredentials;
|
|
2065
|
+
exports.writeHostCredentials = writeHostCredentials;
|
|
2066
|
+
exports.removeHostCredentials = removeHostCredentials;
|
|
2067
|
+
var fs = __importStar(__require("fs"));
|
|
2068
|
+
var path = __importStar(__require("path"));
|
|
2069
|
+
var tokenStore_1 = require_tokenStore();
|
|
2070
|
+
function credentialsFilePath() {
|
|
2071
|
+
return path.join((0, tokenStore_1.ascendaHome)(), "credentials.json");
|
|
2072
|
+
}
|
|
2073
|
+
function readMachineCredentials() {
|
|
2074
|
+
try {
|
|
2075
|
+
const raw = fs.readFileSync(credentialsFilePath(), "utf8").trim();
|
|
2076
|
+
if (!raw)
|
|
2077
|
+
return void 0;
|
|
2078
|
+
const parsed = JSON.parse(raw);
|
|
2079
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
2080
|
+
return void 0;
|
|
2081
|
+
return parsed;
|
|
2082
|
+
} catch {
|
|
2083
|
+
return void 0;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
function writeMachineCredentials(credentials) {
|
|
2087
|
+
const file = credentialsFilePath();
|
|
2088
|
+
fs.mkdirSync(path.dirname(file), { recursive: true, mode: 448 });
|
|
2089
|
+
fs.writeFileSync(file, `${JSON.stringify(credentials, null, 2)}
|
|
2090
|
+
`, { encoding: "utf8", mode: 384 });
|
|
2091
|
+
if (process.platform !== "win32") {
|
|
2092
|
+
fs.chmodSync(path.dirname(file), 448);
|
|
2093
|
+
fs.chmodSync(file, 384);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
function writeTopLevelCredentials(credentials) {
|
|
2097
|
+
const existing = readMachineCredentials();
|
|
2098
|
+
writeMachineCredentials({ ...credentials, ...existing?.tools ? { tools: existing.tools } : {} });
|
|
2099
|
+
}
|
|
2100
|
+
function readHostCredentials(host) {
|
|
2101
|
+
const entry = readMachineCredentials()?.tools?.[host];
|
|
2102
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
2103
|
+
return void 0;
|
|
2104
|
+
return entry;
|
|
2105
|
+
}
|
|
2106
|
+
function writeHostCredentials(host, credentials) {
|
|
2107
|
+
const existing = readMachineCredentials() ?? {};
|
|
2108
|
+
writeMachineCredentials({ ...existing, tools: { ...existing.tools ?? {}, [host]: credentials } });
|
|
2109
|
+
}
|
|
2110
|
+
function removeHostCredentials(host) {
|
|
2111
|
+
const existing = readMachineCredentials();
|
|
2112
|
+
if (!existing?.tools || !(host in existing.tools))
|
|
2113
|
+
return;
|
|
2114
|
+
const tools = { ...existing.tools };
|
|
2115
|
+
delete tools[host];
|
|
2116
|
+
const next = { ...existing };
|
|
2117
|
+
if (Object.keys(tools).length)
|
|
2118
|
+
next.tools = tools;
|
|
2119
|
+
else
|
|
2120
|
+
delete next.tools;
|
|
2121
|
+
writeMachineCredentials(next);
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
});
|
|
2125
|
+
|
|
2126
|
+
// ../packages/tool-kit/out/forgeProject.js
|
|
2127
|
+
var require_forgeProject = __commonJS({
|
|
2128
|
+
"../packages/tool-kit/out/forgeProject.js"(exports) {
|
|
2129
|
+
"use strict";
|
|
2130
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2131
|
+
if (k2 === void 0) k2 = k;
|
|
2132
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2133
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2134
|
+
desc = { enumerable: true, get: function() {
|
|
2135
|
+
return m[k];
|
|
2136
|
+
} };
|
|
2137
|
+
}
|
|
2138
|
+
Object.defineProperty(o, k2, desc);
|
|
2139
|
+
} : function(o, m, k, k2) {
|
|
2140
|
+
if (k2 === void 0) k2 = k;
|
|
2141
|
+
o[k2] = m[k];
|
|
2142
|
+
});
|
|
2143
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
2144
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
2145
|
+
} : function(o, v) {
|
|
2146
|
+
o["default"] = v;
|
|
2147
|
+
});
|
|
2148
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
2149
|
+
var ownKeys = function(o) {
|
|
2150
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
2151
|
+
var ar = [];
|
|
2152
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
2153
|
+
return ar;
|
|
2154
|
+
};
|
|
2155
|
+
return ownKeys(o);
|
|
2156
|
+
};
|
|
2157
|
+
return function(mod) {
|
|
2158
|
+
if (mod && mod.__esModule) return mod;
|
|
2159
|
+
var result = {};
|
|
2160
|
+
if (mod != null) {
|
|
2161
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
2162
|
+
}
|
|
2163
|
+
__setModuleDefault(result, mod);
|
|
2164
|
+
return result;
|
|
2165
|
+
};
|
|
2166
|
+
}();
|
|
2167
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2168
|
+
exports.forgeProjectHash = forgeProjectHash;
|
|
2169
|
+
exports.parseForgeFullName = parseForgeFullName;
|
|
2170
|
+
exports.readForgeFullName = readForgeFullName;
|
|
2171
|
+
exports.forgeFullNameFromConfig = forgeFullNameFromConfig;
|
|
2172
|
+
exports.recordForgeProjectAlias = recordForgeProjectAlias;
|
|
2173
|
+
var fs = __importStar(__require("fs"));
|
|
2174
|
+
var path = __importStar(__require("path"));
|
|
2175
|
+
var contextRegistry_1 = require_contextRegistry();
|
|
2176
|
+
function forgeProjectHash(value) {
|
|
2177
|
+
let h = 2166136261;
|
|
2178
|
+
for (let i = 0; i < value.length; i++) {
|
|
2179
|
+
h ^= value.charCodeAt(i);
|
|
2180
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
2181
|
+
}
|
|
2182
|
+
return h.toString(16).padStart(8, "0");
|
|
2183
|
+
}
|
|
2184
|
+
function parseForgeFullName(remoteUrl) {
|
|
2185
|
+
if (!remoteUrl)
|
|
2186
|
+
return null;
|
|
2187
|
+
const trimmed = remoteUrl.trim();
|
|
2188
|
+
if (!trimmed)
|
|
2189
|
+
return null;
|
|
2190
|
+
const scp = /^(?:[^@/]+@)?([^/:]+):(.+)$/.exec(trimmed);
|
|
2191
|
+
const scheme = /^([a-z][a-z0-9+.-]*):\/\/(?:[^@/]*@)?([^/:]+)(?::\d+)?\/(.+)$/i.exec(trimmed);
|
|
2192
|
+
let host;
|
|
2193
|
+
let repoPath;
|
|
2194
|
+
if (scheme) {
|
|
2195
|
+
host = scheme[2];
|
|
2196
|
+
repoPath = scheme[3];
|
|
2197
|
+
} else if (scp && !/^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed)) {
|
|
2198
|
+
host = scp[1];
|
|
2199
|
+
repoPath = scp[2];
|
|
2200
|
+
} else {
|
|
2201
|
+
return null;
|
|
2202
|
+
}
|
|
2203
|
+
const normalizedHost = host.toLowerCase().replace(/^www\./, "");
|
|
2204
|
+
if (normalizedHost !== "github.com")
|
|
2205
|
+
return null;
|
|
2206
|
+
const segments = repoPath.split("/").filter((segment) => segment.length > 0);
|
|
2207
|
+
if (segments.length < 2)
|
|
2208
|
+
return null;
|
|
2209
|
+
const owner = segments[0];
|
|
2210
|
+
const repo = segments[1].replace(/\.git$/, "");
|
|
2211
|
+
if (!owner || !repo)
|
|
2212
|
+
return null;
|
|
2213
|
+
return `${owner}/${repo}`;
|
|
2214
|
+
}
|
|
2215
|
+
function readForgeFullName(repositoryRoot) {
|
|
2216
|
+
if (!repositoryRoot)
|
|
2217
|
+
return null;
|
|
2218
|
+
let config2;
|
|
2219
|
+
try {
|
|
2220
|
+
config2 = fs.readFileSync(path.join(repositoryRoot, ".git", "config"), "utf8");
|
|
2221
|
+
} catch {
|
|
2222
|
+
return null;
|
|
2223
|
+
}
|
|
2224
|
+
return forgeFullNameFromConfig(config2);
|
|
2225
|
+
}
|
|
2226
|
+
function forgeFullNameFromConfig(config2) {
|
|
2227
|
+
const remotes = /* @__PURE__ */ new Map();
|
|
2228
|
+
let currentRemote = null;
|
|
2229
|
+
for (const rawLine of config2.split(/\r?\n/)) {
|
|
2230
|
+
const line = rawLine.trim();
|
|
2231
|
+
if (!line || line.startsWith("#") || line.startsWith(";"))
|
|
2232
|
+
continue;
|
|
2233
|
+
const section = /^\[([^\]]*)\]$/.exec(line);
|
|
2234
|
+
if (section) {
|
|
2235
|
+
const remote = /^remote\s+"(.*)"$/.exec(section[1].trim());
|
|
2236
|
+
currentRemote = remote ? remote[1] : null;
|
|
2237
|
+
continue;
|
|
2238
|
+
}
|
|
2239
|
+
if (!currentRemote)
|
|
2240
|
+
continue;
|
|
2241
|
+
const entry = /^url\s*=\s*(.*)$/.exec(line);
|
|
2242
|
+
if (entry && !remotes.has(currentRemote))
|
|
2243
|
+
remotes.set(currentRemote, entry[1].trim());
|
|
2244
|
+
}
|
|
2245
|
+
const ordered = [
|
|
2246
|
+
...remotes.has("origin") ? ["origin"] : [],
|
|
2247
|
+
...remotes.has("upstream") ? ["upstream"] : [],
|
|
2248
|
+
...[...remotes.keys()].filter((name) => name !== "origin" && name !== "upstream")
|
|
2249
|
+
];
|
|
2250
|
+
for (const name of ordered) {
|
|
2251
|
+
const fullName = parseForgeFullName(remotes.get(name));
|
|
2252
|
+
if (fullName)
|
|
2253
|
+
return fullName;
|
|
2254
|
+
}
|
|
2255
|
+
return null;
|
|
2256
|
+
}
|
|
2257
|
+
function recordForgeProjectAlias(context, options) {
|
|
2258
|
+
try {
|
|
2259
|
+
if (!context?.projectHash || !context.projectLabel || !context.projectPath)
|
|
2260
|
+
return false;
|
|
2261
|
+
const fullName = readForgeFullName(context.projectPath);
|
|
2262
|
+
if (!fullName)
|
|
2263
|
+
return false;
|
|
2264
|
+
const variants = [fullName, fullName.toLowerCase()].filter((value, index, all) => all.indexOf(value) === index);
|
|
2265
|
+
let wrote = false;
|
|
2266
|
+
for (const variant of variants) {
|
|
2267
|
+
const hash = forgeProjectHash(variant);
|
|
2268
|
+
if (hash === context.projectHash || hash === context.workspaceHash)
|
|
2269
|
+
continue;
|
|
2270
|
+
if ((0, contextRegistry_1.recordWorkContextAlias)(hash, context.projectLabel, context.projectPath, options))
|
|
2271
|
+
wrote = true;
|
|
2272
|
+
}
|
|
2273
|
+
return wrote;
|
|
2274
|
+
} catch {
|
|
2275
|
+
return false;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
});
|
|
2280
|
+
|
|
1348
2281
|
// ../packages/tool-kit/out/salt.js
|
|
1349
2282
|
var require_salt = __commonJS({
|
|
1350
2283
|
"../packages/tool-kit/out/salt.js"(exports) {
|
|
@@ -1471,6 +2404,10 @@ var require_workContext = __commonJS({
|
|
|
1471
2404
|
}();
|
|
1472
2405
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1473
2406
|
exports.deriveWorkContext = deriveWorkContext;
|
|
2407
|
+
exports.normalizeBranchName = normalizeBranchName;
|
|
2408
|
+
exports.deriveBranchHash = deriveBranchHash;
|
|
2409
|
+
exports.readBranchName = readBranchName;
|
|
2410
|
+
exports.deriveBranchHashForCwd = deriveBranchHashForCwd;
|
|
1474
2411
|
var fs = __importStar(__require("fs"));
|
|
1475
2412
|
var path = __importStar(__require("path"));
|
|
1476
2413
|
var salt_1 = require_salt();
|
|
@@ -1485,6 +2422,8 @@ var require_workContext = __commonJS({
|
|
|
1485
2422
|
} catch {
|
|
1486
2423
|
roots = null;
|
|
1487
2424
|
}
|
|
2425
|
+
if (!roots)
|
|
2426
|
+
roots = inferRootsFromPath(startPath);
|
|
1488
2427
|
const workspacePath = roots?.checkoutRoot ?? startPath;
|
|
1489
2428
|
const workspaceLabel = basenameOf(workspacePath);
|
|
1490
2429
|
if (!workspaceLabel)
|
|
@@ -1513,9 +2452,12 @@ var require_workContext = __commonJS({
|
|
|
1513
2452
|
stat = null;
|
|
1514
2453
|
}
|
|
1515
2454
|
if (stat?.isDirectory())
|
|
1516
|
-
return { checkoutRoot: dir, canonicalRoot: dir };
|
|
1517
|
-
if (stat?.isFile())
|
|
1518
|
-
|
|
2455
|
+
return { checkoutRoot: dir, canonicalRoot: dir, gitDir: dotGit };
|
|
2456
|
+
if (stat?.isFile()) {
|
|
2457
|
+
const gitDir = readGitdirPointer(dotGit, dir);
|
|
2458
|
+
const canonicalRoot = (gitDir ? worktreeParentRoot(gitDir) : null) ?? dir;
|
|
2459
|
+
return { checkoutRoot: dir, canonicalRoot, gitDir };
|
|
2460
|
+
}
|
|
1519
2461
|
const parent = path.dirname(dir);
|
|
1520
2462
|
if (parent === dir)
|
|
1521
2463
|
return null;
|
|
@@ -1523,22 +2465,45 @@ var require_workContext = __commonJS({
|
|
|
1523
2465
|
}
|
|
1524
2466
|
return null;
|
|
1525
2467
|
}
|
|
1526
|
-
function
|
|
1527
|
-
let gitdir;
|
|
2468
|
+
function readGitdirPointer(dotGitFile, containingDir) {
|
|
1528
2469
|
try {
|
|
1529
2470
|
const match = /^gitdir:\s*(.+)\s*$/m.exec(fs.readFileSync(dotGitFile, "utf8"));
|
|
1530
2471
|
if (!match)
|
|
1531
2472
|
return null;
|
|
1532
|
-
|
|
2473
|
+
return path.resolve(containingDir, match[1].trim());
|
|
1533
2474
|
} catch {
|
|
1534
2475
|
return null;
|
|
1535
2476
|
}
|
|
1536
|
-
|
|
2477
|
+
}
|
|
2478
|
+
function worktreeParentRoot(resolvedGitDir) {
|
|
1537
2479
|
const marker = `${path.sep}.git${path.sep}worktrees${path.sep}`;
|
|
1538
|
-
const idx =
|
|
2480
|
+
const idx = resolvedGitDir.indexOf(marker);
|
|
1539
2481
|
if (idx === -1)
|
|
1540
2482
|
return null;
|
|
1541
|
-
return
|
|
2483
|
+
return resolvedGitDir.slice(0, idx);
|
|
2484
|
+
}
|
|
2485
|
+
function inferRootsFromPath(startPath) {
|
|
2486
|
+
const sep = startPath.includes("\\") && !startPath.includes("/") ? "\\" : "/";
|
|
2487
|
+
const leading = /^[\\/]/.test(startPath) ? sep : "";
|
|
2488
|
+
const segments = startPath.split(/[\\/]/).filter(Boolean);
|
|
2489
|
+
const join = (count) => leading + segments.slice(0, count).join(sep);
|
|
2490
|
+
for (let i = 0; i + 2 < segments.length; i++) {
|
|
2491
|
+
if (segments[i] === ".claude" && segments[i + 1] === "worktrees") {
|
|
2492
|
+
if (i === 0)
|
|
2493
|
+
return null;
|
|
2494
|
+
return { checkoutRoot: join(i + 3), canonicalRoot: join(i), gitDir: null };
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
for (let i = 0; i + 1 < segments.length; i++) {
|
|
2498
|
+
const folder = segments[i];
|
|
2499
|
+
const suffix = ["-worktrees", "-wt"].find((s) => folder.endsWith(s) && folder.length > s.length);
|
|
2500
|
+
if (!suffix)
|
|
2501
|
+
continue;
|
|
2502
|
+
const repoName = folder.slice(0, -suffix.length);
|
|
2503
|
+
const canonicalRoot = leading + [...segments.slice(0, i), repoName].join(sep);
|
|
2504
|
+
return { checkoutRoot: join(i + 2), canonicalRoot, gitDir: null };
|
|
2505
|
+
}
|
|
2506
|
+
return null;
|
|
1542
2507
|
}
|
|
1543
2508
|
function stripTrailingSeparators(value) {
|
|
1544
2509
|
let end = value.length;
|
|
@@ -1550,6 +2515,55 @@ var require_workContext = __commonJS({
|
|
|
1550
2515
|
const segment = value.split(/[\\/]/).filter(Boolean).pop() ?? null;
|
|
1551
2516
|
return segment && segment.length > 0 ? segment : null;
|
|
1552
2517
|
}
|
|
2518
|
+
var REFS_HEADS_PREFIX = "refs/heads/";
|
|
2519
|
+
function normalizeBranchName(branch) {
|
|
2520
|
+
if (!branch)
|
|
2521
|
+
return null;
|
|
2522
|
+
let name = branch.trim();
|
|
2523
|
+
if (name.startsWith(REFS_HEADS_PREFIX))
|
|
2524
|
+
name = name.slice(REFS_HEADS_PREFIX.length).trim();
|
|
2525
|
+
if (!name || name === "HEAD")
|
|
2526
|
+
return null;
|
|
2527
|
+
return name;
|
|
2528
|
+
}
|
|
2529
|
+
function deriveBranchHash(branch, saltFilePath) {
|
|
2530
|
+
const name = normalizeBranchName(branch);
|
|
2531
|
+
if (!name)
|
|
2532
|
+
return null;
|
|
2533
|
+
try {
|
|
2534
|
+
return (0, salt_1.hashWithMachineSalt)(name, saltFilePath);
|
|
2535
|
+
} catch {
|
|
2536
|
+
return null;
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
function readBranchName(cwd) {
|
|
2540
|
+
if (!cwd || !cwd.trim())
|
|
2541
|
+
return null;
|
|
2542
|
+
let gitDir = null;
|
|
2543
|
+
try {
|
|
2544
|
+
gitDir = resolveRepositoryRoots(stripTrailingSeparators(cwd.trim()))?.gitDir ?? null;
|
|
2545
|
+
} catch {
|
|
2546
|
+
gitDir = null;
|
|
2547
|
+
}
|
|
2548
|
+
if (!gitDir)
|
|
2549
|
+
return null;
|
|
2550
|
+
let head;
|
|
2551
|
+
try {
|
|
2552
|
+
head = fs.readFileSync(path.join(gitDir, "HEAD"), "utf8").trim();
|
|
2553
|
+
} catch {
|
|
2554
|
+
return null;
|
|
2555
|
+
}
|
|
2556
|
+
const match = /^ref:\s*(.+)$/.exec(head);
|
|
2557
|
+
if (!match)
|
|
2558
|
+
return null;
|
|
2559
|
+
const ref = match[1].trim();
|
|
2560
|
+
if (!ref.startsWith(REFS_HEADS_PREFIX))
|
|
2561
|
+
return null;
|
|
2562
|
+
return normalizeBranchName(ref);
|
|
2563
|
+
}
|
|
2564
|
+
function deriveBranchHashForCwd(cwd, saltFilePath) {
|
|
2565
|
+
return deriveBranchHash(readBranchName(cwd), saltFilePath);
|
|
2566
|
+
}
|
|
1553
2567
|
}
|
|
1554
2568
|
});
|
|
1555
2569
|
|
|
@@ -1558,35 +2572,69 @@ var require_hookAdapter = __commonJS({
|
|
|
1558
2572
|
"../packages/tool-kit/out/hookAdapter.js"(exports) {
|
|
1559
2573
|
"use strict";
|
|
1560
2574
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1561
|
-
exports.DEFAULT_API_BASE_URL = void 0;
|
|
2575
|
+
exports.MissingInstallationIdError = exports.DEFAULT_API_BASE_URL = void 0;
|
|
2576
|
+
exports.resolveCliAgentInstallationId = resolveCliAgentInstallationId;
|
|
1562
2577
|
exports.resolveContextHashes = resolveContextHashes;
|
|
1563
2578
|
exports.loadCliAgentConfig = loadCliAgentConfig;
|
|
1564
2579
|
exports.deliverHookEvents = deliverHookEvents;
|
|
1565
2580
|
var contextRegistry_1 = require_contextRegistry();
|
|
2581
|
+
var credentials_1 = require_credentials();
|
|
2582
|
+
var forgeProject_1 = require_forgeProject();
|
|
1566
2583
|
var eventLog_1 = require_eventLog();
|
|
1567
2584
|
var eventSender_1 = require_eventSender();
|
|
2585
|
+
var stateStore_1 = require_stateStore();
|
|
1568
2586
|
var tokenStore_1 = require_tokenStore();
|
|
1569
2587
|
var workContext_1 = require_workContext();
|
|
1570
2588
|
exports.DEFAULT_API_BASE_URL = "https://api.ascenda.one";
|
|
2589
|
+
var MissingInstallationIdError = class extends Error {
|
|
2590
|
+
/** The token files that were considered — none, or too many to pick from. */
|
|
2591
|
+
candidates;
|
|
2592
|
+
toolType;
|
|
2593
|
+
constructor(toolType, candidates, setupCommand) {
|
|
2594
|
+
super(candidates.length === 0 ? `Not configured: no ASCENDA_TOOL_INSTALLATION_ID, no pairing in ~/.ascenda/credentials.json, and no ${toolType} token in ~/.ascenda/tokens/. Run: ${setupCommand}` : `Not configured: no ASCENDA_TOOL_INSTALLATION_ID, no pairing in ~/.ascenda/credentials.json, and ${candidates.length} ${toolType} tokens in ~/.ascenda/tokens/ (${candidates.join(", ")}) \u2014 refusing to guess. Export ASCENDA_TOOL_INSTALLATION_ID to choose one, or run: ${setupCommand}`);
|
|
2595
|
+
this.name = "MissingInstallationIdError";
|
|
2596
|
+
this.toolType = toolType;
|
|
2597
|
+
this.candidates = candidates;
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
exports.MissingInstallationIdError = MissingInstallationIdError;
|
|
2601
|
+
function resolveCliAgentInstallationId(toolType, identity = {}) {
|
|
2602
|
+
const fromEnv = process.env.ASCENDA_TOOL_INSTALLATION_ID?.trim();
|
|
2603
|
+
if (fromEnv)
|
|
2604
|
+
return { toolInstallationId: qualify(toolType, fromEnv), source: "env" };
|
|
2605
|
+
const fromCredentials = identity.host ? (0, credentials_1.readHostCredentials)(identity.host)?.toolInstallationId?.trim() : void 0;
|
|
2606
|
+
if (fromCredentials)
|
|
2607
|
+
return { toolInstallationId: qualify(toolType, fromCredentials), source: "credentials" };
|
|
2608
|
+
const candidates = (0, tokenStore_1.listPersistedToolInstallationIds)(toolType);
|
|
2609
|
+
if (candidates.length === 1)
|
|
2610
|
+
return { toolInstallationId: candidates[0], source: "disk" };
|
|
2611
|
+
throw new MissingInstallationIdError(toolType, candidates, identity.setupCommand ?? defaultSetupCommand(identity.host));
|
|
2612
|
+
}
|
|
2613
|
+
function defaultSetupCommand(host) {
|
|
2614
|
+
return host ? `npx @ascenda-one/${host.replace(/_cli$/, "")}-hooks setup` : "the agent's setup command";
|
|
2615
|
+
}
|
|
2616
|
+
function qualify(toolType, value) {
|
|
2617
|
+
return value.includes(":") ? value : `${toolType}:${value}`;
|
|
2618
|
+
}
|
|
1571
2619
|
function resolveContextHashes(cwd) {
|
|
1572
2620
|
const workspaceOverride = process.env.ASCENDA_WORKSPACE_HASH?.trim() || null;
|
|
1573
2621
|
const projectOverride = process.env.ASCENDA_PROJECT_HASH?.trim() || null;
|
|
1574
2622
|
if (workspaceOverride && projectOverride)
|
|
1575
2623
|
return { workspaceHash: workspaceOverride, projectHash: projectOverride };
|
|
1576
2624
|
const context = (0, workContext_1.deriveWorkContext)(cwd ?? process.cwd());
|
|
1577
|
-
if (context)
|
|
2625
|
+
if (context) {
|
|
1578
2626
|
(0, contextRegistry_1.recordWorkContext)(context);
|
|
2627
|
+
(0, forgeProject_1.recordForgeProjectAlias)(context);
|
|
2628
|
+
}
|
|
1579
2629
|
return {
|
|
1580
2630
|
workspaceHash: workspaceOverride ?? context?.workspaceHash ?? null,
|
|
1581
2631
|
projectHash: projectOverride ?? context?.projectHash ?? null
|
|
1582
2632
|
};
|
|
1583
2633
|
}
|
|
1584
|
-
function loadCliAgentConfig(toolType, sessionIdFromHook, cwd) {
|
|
1585
|
-
const
|
|
1586
|
-
const
|
|
1587
|
-
|
|
1588
|
-
throw new Error("Missing ASCENDA_TOOL_INSTALLATION_ID");
|
|
1589
|
-
const toolInstallationId = toolInstallationIdRaw.trim().includes(":") ? toolInstallationIdRaw.trim() : `${toolType}:${toolInstallationIdRaw.trim()}`;
|
|
2634
|
+
function loadCliAgentConfig(toolType, sessionIdFromHook, cwd, identity = {}) {
|
|
2635
|
+
const credentials = identity.host ? (0, credentials_1.readHostCredentials)(identity.host) : void 0;
|
|
2636
|
+
const apiBaseUrl = (process.env.ASCENDA_API_BASE_URL ?? credentials?.apiBaseUrl ?? exports.DEFAULT_API_BASE_URL).replace(/\/$/, "");
|
|
2637
|
+
const { toolInstallationId } = resolveCliAgentInstallationId(toolType, identity);
|
|
1590
2638
|
const tokenFilePath = process.env.ASCENDA_EVENT_WRITE_TOKEN_FILE ?? (0, tokenStore_1.defaultTokenFilePath)(toolInstallationId);
|
|
1591
2639
|
const fileToken = (0, tokenStore_1.readTokenFile)(tokenFilePath);
|
|
1592
2640
|
const eventWriteToken = fileToken ?? process.env.ASCENDA_EVENT_WRITE_TOKEN;
|
|
@@ -1600,7 +2648,10 @@ var require_hookAdapter = __commonJS({
|
|
|
1600
2648
|
toolInstallationId,
|
|
1601
2649
|
eventWriteToken,
|
|
1602
2650
|
tokenFilePath,
|
|
1603
|
-
|
|
2651
|
+
// An empty ASCENDA_SESSION_ID is "unset", not "override with nothing":
|
|
2652
|
+
// read raw, `ASCENDA_SESSION_ID=""` beat a real hook session and shipped
|
|
2653
|
+
// an empty string, grouping unrelated rows under a value naming no session.
|
|
2654
|
+
sessionId: process.env.ASCENDA_SESSION_ID?.trim() || sessionIdFromHook || null,
|
|
1604
2655
|
workspaceHash: contextHashes.workspaceHash,
|
|
1605
2656
|
projectHash: contextHashes.projectHash,
|
|
1606
2657
|
// Agents await command hooks; fail fast rather than stall the user's turn.
|
|
@@ -1613,8 +2664,10 @@ var require_hookAdapter = __commonJS({
|
|
|
1613
2664
|
const notice = options.onNotice ?? ((message) => console.error(message));
|
|
1614
2665
|
let config2;
|
|
1615
2666
|
try {
|
|
1616
|
-
config2 = loadCliAgentConfig(options.toolType, options.sessionId, options.cwd);
|
|
2667
|
+
config2 = loadCliAgentConfig(options.toolType, options.sessionId, options.cwd, options);
|
|
1617
2668
|
} catch (error2) {
|
|
2669
|
+
if (error2 instanceof MissingInstallationIdError)
|
|
2670
|
+
journalSkippedSend(options.host, error2);
|
|
1618
2671
|
const logFile = (0, eventLog_1.resolveEventLogPath)();
|
|
1619
2672
|
if (!logFile)
|
|
1620
2673
|
throw error2;
|
|
@@ -1654,13 +2707,19 @@ var require_hookAdapter = __commonJS({
|
|
|
1654
2707
|
} else if (result === "auth_failed") {
|
|
1655
2708
|
notice("Ascenda telemetry paused: connection revoked or expired. Re-pair via an Ascenda IDE extension or pairing-sim.");
|
|
1656
2709
|
} else if (result === "transport_error") {
|
|
1657
|
-
notice("Ascenda telemetry paused: the ingest endpoint could not be reached. Your work is unaffected.");
|
|
2710
|
+
notice("Ascenda telemetry paused: the ingest endpoint could not be reached; the event is kept in the outbox. Your work is unaffected.");
|
|
1658
2711
|
} else {
|
|
1659
2712
|
notice(`Ascenda telemetry rejected: ${result}`);
|
|
1660
2713
|
}
|
|
1661
2714
|
return;
|
|
1662
2715
|
}
|
|
1663
2716
|
}
|
|
2717
|
+
function journalSkippedSend(host, error2) {
|
|
2718
|
+
const who = host ? `${host}: ` : "";
|
|
2719
|
+
(0, stateStore_1.recordSendOutcome)((0, stateStore_1.unresolvedStateFilePath)(error2.toolType), (0, stateStore_1.unresolvedToolInstallationId)(error2.toolType), "skipped_no_installation_id", {
|
|
2720
|
+
detail: error2.candidates.length === 0 ? `${who}no ASCENDA_TOOL_INSTALLATION_ID, no credentials.json pairing, no ${error2.toolType} token file` : `${who}no ASCENDA_TOOL_INSTALLATION_ID, no credentials.json pairing, ${error2.candidates.length} ${error2.toolType} token files (${error2.candidates.join(", ")})`
|
|
2721
|
+
});
|
|
2722
|
+
}
|
|
1664
2723
|
function parsePositiveInt(value) {
|
|
1665
2724
|
const n = Number(value);
|
|
1666
2725
|
return Number.isInteger(n) && n > 0 ? n : void 0;
|
|
@@ -1668,6 +2727,387 @@ var require_hookAdapter = __commonJS({
|
|
|
1668
2727
|
}
|
|
1669
2728
|
});
|
|
1670
2729
|
|
|
2730
|
+
// ../packages/tool-kit/out/cliAgentSetup.js
|
|
2731
|
+
var require_cliAgentSetup = __commonJS({
|
|
2732
|
+
"../packages/tool-kit/out/cliAgentSetup.js"(exports) {
|
|
2733
|
+
"use strict";
|
|
2734
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2735
|
+
if (k2 === void 0) k2 = k;
|
|
2736
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2737
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2738
|
+
desc = { enumerable: true, get: function() {
|
|
2739
|
+
return m[k];
|
|
2740
|
+
} };
|
|
2741
|
+
}
|
|
2742
|
+
Object.defineProperty(o, k2, desc);
|
|
2743
|
+
} : function(o, m, k, k2) {
|
|
2744
|
+
if (k2 === void 0) k2 = k;
|
|
2745
|
+
o[k2] = m[k];
|
|
2746
|
+
});
|
|
2747
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
2748
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
2749
|
+
} : function(o, v) {
|
|
2750
|
+
o["default"] = v;
|
|
2751
|
+
});
|
|
2752
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
2753
|
+
var ownKeys = function(o) {
|
|
2754
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
2755
|
+
var ar = [];
|
|
2756
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
2757
|
+
return ar;
|
|
2758
|
+
};
|
|
2759
|
+
return ownKeys(o);
|
|
2760
|
+
};
|
|
2761
|
+
return function(mod) {
|
|
2762
|
+
if (mod && mod.__esModule) return mod;
|
|
2763
|
+
var result = {};
|
|
2764
|
+
if (mod != null) {
|
|
2765
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
2766
|
+
}
|
|
2767
|
+
__setModuleDefault(result, mod);
|
|
2768
|
+
return result;
|
|
2769
|
+
};
|
|
2770
|
+
}();
|
|
2771
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2772
|
+
exports.isCliAgentManagementCommand = isCliAgentManagementCommand;
|
|
2773
|
+
exports.cliAgentHookBinPath = cliAgentHookBinPath;
|
|
2774
|
+
exports.runCliAgentSetup = runCliAgentSetup;
|
|
2775
|
+
exports.writeHookSettings = writeHookSettings;
|
|
2776
|
+
exports.findStaleHookCommands = findStaleHookCommands;
|
|
2777
|
+
var crypto = __importStar(__require("crypto"));
|
|
2778
|
+
var fs = __importStar(__require("fs"));
|
|
2779
|
+
var os = __importStar(__require("os"));
|
|
2780
|
+
var path = __importStar(__require("path"));
|
|
2781
|
+
var credentials_1 = require_credentials();
|
|
2782
|
+
var hookAdapter_1 = require_hookAdapter();
|
|
2783
|
+
var http_1 = require_http();
|
|
2784
|
+
var tokenStore_1 = require_tokenStore();
|
|
2785
|
+
var MANAGEMENT_COMMANDS = /* @__PURE__ */ new Set(["setup", "install", "status", "uninstall", "-h", "--help"]);
|
|
2786
|
+
function isCliAgentManagementCommand(argument) {
|
|
2787
|
+
return argument !== void 0 && MANAGEMENT_COMMANDS.has(argument);
|
|
2788
|
+
}
|
|
2789
|
+
function cliAgentHookBinPath(binaryName) {
|
|
2790
|
+
return path.join((0, tokenStore_1.ascendaHome)(), "bin", binaryName);
|
|
2791
|
+
}
|
|
2792
|
+
function usage(spec) {
|
|
2793
|
+
return `${spec.binaryName} setup \u2014 wire ${spec.displayName} to Ascenda telemetry
|
|
2794
|
+
|
|
2795
|
+
npx ${spec.packageName} setup [options]
|
|
2796
|
+
npx ${spec.packageName} status
|
|
2797
|
+
npx ${spec.packageName} uninstall
|
|
2798
|
+
|
|
2799
|
+
Options
|
|
2800
|
+
--api-base-url <url> ingest host (default ${hookAdapter_1.DEFAULT_API_BASE_URL})
|
|
2801
|
+
--local [port] shorthand for the local dev server (default port 4477)
|
|
2802
|
+
--tool-installation-id <id> reuse an existing pairing instead of creating one
|
|
2803
|
+
--token <eventWriteToken> reuse an existing token (stored 0600, never printed)
|
|
2804
|
+
--scope project|user where hooks are registered (default project)
|
|
2805
|
+
--project-dir <path> project root for --scope project (default cwd)
|
|
2806
|
+
--dry-run print what would change, write nothing
|
|
2807
|
+
-h, --help
|
|
2808
|
+
`;
|
|
2809
|
+
}
|
|
2810
|
+
async function runCliAgentSetup(argv, spec) {
|
|
2811
|
+
let options;
|
|
2812
|
+
try {
|
|
2813
|
+
options = parseArgs(argv, spec);
|
|
2814
|
+
} catch (error2) {
|
|
2815
|
+
console.error(error2 instanceof Error ? error2.message : String(error2));
|
|
2816
|
+
return 1;
|
|
2817
|
+
}
|
|
2818
|
+
if (options.action === "help") {
|
|
2819
|
+
console.log(usage(spec));
|
|
2820
|
+
return 0;
|
|
2821
|
+
}
|
|
2822
|
+
if (options.action === "status")
|
|
2823
|
+
return printStatus(options, spec);
|
|
2824
|
+
if (options.action === "uninstall")
|
|
2825
|
+
return uninstall(options, spec);
|
|
2826
|
+
const apiBaseUrl = (options.apiBaseUrl ?? (0, credentials_1.readHostCredentials)(spec.host)?.apiBaseUrl ?? hookAdapter_1.DEFAULT_API_BASE_URL).replace(/\/$/, "");
|
|
2827
|
+
console.log(`Ascenda setup for ${spec.displayName} \u2014 ${apiBaseUrl}`);
|
|
2828
|
+
const identity = await resolveIdentity(apiBaseUrl, options, spec);
|
|
2829
|
+
if (!identity)
|
|
2830
|
+
return 1;
|
|
2831
|
+
console.log(` pairing ${identity.toolInstallationId}${identity.paired ? " (new)" : " (existing)"}`);
|
|
2832
|
+
const binary = installBinary(spec, options.dryRun);
|
|
2833
|
+
console.log(` hook binary ${binary}`);
|
|
2834
|
+
if (!options.dryRun) {
|
|
2835
|
+
(0, credentials_1.writeHostCredentials)(spec.host, { apiBaseUrl, toolInstallationId: identity.toolInstallationId, pairedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
2836
|
+
}
|
|
2837
|
+
console.log(` credentials ${(0, credentials_1.credentialsFilePath)()} (tools.${spec.host})`);
|
|
2838
|
+
const settingsFile = spec.settings.settingsPath(options.scope, options.projectDir);
|
|
2839
|
+
const written = writeHookSettings(settingsFile, binary, spec, options.dryRun);
|
|
2840
|
+
if (written === null)
|
|
2841
|
+
return 1;
|
|
2842
|
+
console.log(` hooks ${settingsFile} (${spec.hookEvents.length} events${written ? "" : ", already current"})`);
|
|
2843
|
+
if (options.dryRun) {
|
|
2844
|
+
console.log("\nDry run \u2014 nothing was written.");
|
|
2845
|
+
return 0;
|
|
2846
|
+
}
|
|
2847
|
+
console.log(`
|
|
2848
|
+
Done. ${spec.restartHint}`);
|
|
2849
|
+
console.log(`Check anytime: npx ${spec.packageName} status`);
|
|
2850
|
+
return 0;
|
|
2851
|
+
}
|
|
2852
|
+
function parseArgs(argv, spec) {
|
|
2853
|
+
const options = {
|
|
2854
|
+
scope: "project",
|
|
2855
|
+
projectDir: process.cwd(),
|
|
2856
|
+
dryRun: false,
|
|
2857
|
+
action: "install"
|
|
2858
|
+
};
|
|
2859
|
+
for (let i = 0; i < argv.length; i++) {
|
|
2860
|
+
const arg = argv[i];
|
|
2861
|
+
const next = () => {
|
|
2862
|
+
const value = argv[++i];
|
|
2863
|
+
if (value === void 0)
|
|
2864
|
+
throw new Error(`${arg} needs a value`);
|
|
2865
|
+
return value;
|
|
2866
|
+
};
|
|
2867
|
+
switch (arg) {
|
|
2868
|
+
case "setup":
|
|
2869
|
+
case "install":
|
|
2870
|
+
options.action = "install";
|
|
2871
|
+
break;
|
|
2872
|
+
case "status":
|
|
2873
|
+
options.action = "status";
|
|
2874
|
+
break;
|
|
2875
|
+
case "uninstall":
|
|
2876
|
+
options.action = "uninstall";
|
|
2877
|
+
break;
|
|
2878
|
+
case "--api-base-url":
|
|
2879
|
+
options.apiBaseUrl = next();
|
|
2880
|
+
break;
|
|
2881
|
+
case "--local": {
|
|
2882
|
+
const peek = argv[i + 1];
|
|
2883
|
+
const port = peek && /^\d+$/.test(peek) ? argv[++i] : "4477";
|
|
2884
|
+
options.apiBaseUrl = `http://localhost:${port}`;
|
|
2885
|
+
break;
|
|
2886
|
+
}
|
|
2887
|
+
case "--tool-installation-id":
|
|
2888
|
+
options.toolInstallationId = next();
|
|
2889
|
+
break;
|
|
2890
|
+
case "--token":
|
|
2891
|
+
options.token = next();
|
|
2892
|
+
break;
|
|
2893
|
+
case "--scope": {
|
|
2894
|
+
const value = next();
|
|
2895
|
+
if (value !== "project" && value !== "user")
|
|
2896
|
+
throw new Error(`--scope must be project or user, got ${value}`);
|
|
2897
|
+
options.scope = value;
|
|
2898
|
+
break;
|
|
2899
|
+
}
|
|
2900
|
+
case "--project-dir":
|
|
2901
|
+
options.projectDir = path.resolve(next());
|
|
2902
|
+
break;
|
|
2903
|
+
case "--dry-run":
|
|
2904
|
+
options.dryRun = true;
|
|
2905
|
+
break;
|
|
2906
|
+
case "-h":
|
|
2907
|
+
case "--help":
|
|
2908
|
+
options.action = "help";
|
|
2909
|
+
break;
|
|
2910
|
+
default:
|
|
2911
|
+
throw new Error(`unknown argument: ${arg}
|
|
2912
|
+
|
|
2913
|
+
${usage(spec)}`);
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
return options;
|
|
2917
|
+
}
|
|
2918
|
+
async function resolveIdentity(apiBaseUrl, options, spec) {
|
|
2919
|
+
const existingId = options.toolInstallationId ?? (0, credentials_1.readHostCredentials)(spec.host)?.toolInstallationId;
|
|
2920
|
+
if (existingId && options.token) {
|
|
2921
|
+
if (!options.dryRun)
|
|
2922
|
+
(0, tokenStore_1.persistEventWriteToken)((0, tokenStore_1.defaultTokenFilePath)(existingId), options.token);
|
|
2923
|
+
return { toolInstallationId: existingId, paired: false };
|
|
2924
|
+
}
|
|
2925
|
+
if (existingId && (0, tokenStore_1.readTokenFile)((0, tokenStore_1.defaultTokenFilePath)(existingId))) {
|
|
2926
|
+
return { toolInstallationId: existingId, paired: false };
|
|
2927
|
+
}
|
|
2928
|
+
if (options.dryRun) {
|
|
2929
|
+
return { toolInstallationId: existingId ?? `${spec.toolType}:<paired at run time>`, paired: false };
|
|
2930
|
+
}
|
|
2931
|
+
const toolInstallationId = existingId ?? `${spec.toolType}:${crypto.randomUUID()}`;
|
|
2932
|
+
let session;
|
|
2933
|
+
try {
|
|
2934
|
+
session = await (0, http_1.createPairingSession)(apiBaseUrl, toolInstallationId, spec.toolType, `${spec.displayName} on ${os.hostname()}`);
|
|
2935
|
+
} catch (error2) {
|
|
2936
|
+
console.error(`
|
|
2937
|
+
Could not reach ${apiBaseUrl} to pair: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
2938
|
+
console.error("Start the local dev server and use --local, or pass --api-base-url for your backend.");
|
|
2939
|
+
return void 0;
|
|
2940
|
+
}
|
|
2941
|
+
const token = await pollForToken(apiBaseUrl, session.pairingSessionId, session.code, session.expiresAt);
|
|
2942
|
+
if (!token)
|
|
2943
|
+
return void 0;
|
|
2944
|
+
(0, tokenStore_1.persistEventWriteToken)((0, tokenStore_1.defaultTokenFilePath)(toolInstallationId), token);
|
|
2945
|
+
return { toolInstallationId, paired: true };
|
|
2946
|
+
}
|
|
2947
|
+
async function pollForToken(apiBaseUrl, pairingSessionId, code, expiresAt) {
|
|
2948
|
+
const deadline = Math.min(Date.parse(expiresAt) || Date.now() + 3e5, Date.now() + 3e5);
|
|
2949
|
+
let announced = false;
|
|
2950
|
+
while (Date.now() < deadline) {
|
|
2951
|
+
const status = await (0, http_1.getPairingStatus)(apiBaseUrl, pairingSessionId);
|
|
2952
|
+
if (status.status === "paired" && status.eventWriteToken)
|
|
2953
|
+
return status.eventWriteToken;
|
|
2954
|
+
if (status.status === "expired" || status.status === "cancelled") {
|
|
2955
|
+
console.error(`
|
|
2956
|
+
Pairing ${status.status}. Run setup again.`);
|
|
2957
|
+
return void 0;
|
|
2958
|
+
}
|
|
2959
|
+
if (!announced) {
|
|
2960
|
+
console.log(`
|
|
2961
|
+
Confirm in the Ascenda app \u2014 code ${code}`);
|
|
2962
|
+
console.log(" Waiting...");
|
|
2963
|
+
announced = true;
|
|
2964
|
+
}
|
|
2965
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
2966
|
+
}
|
|
2967
|
+
console.error("\nPairing timed out. Run setup again.");
|
|
2968
|
+
return void 0;
|
|
2969
|
+
}
|
|
2970
|
+
function installBinary(spec, dryRun) {
|
|
2971
|
+
const target = cliAgentHookBinPath(spec.binaryName);
|
|
2972
|
+
if (dryRun)
|
|
2973
|
+
return target;
|
|
2974
|
+
const source = process.argv[1];
|
|
2975
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
2976
|
+
if (path.resolve(source) !== path.resolve(target)) {
|
|
2977
|
+
fs.copyFileSync(source, target);
|
|
2978
|
+
}
|
|
2979
|
+
if (process.platform !== "win32")
|
|
2980
|
+
fs.chmodSync(target, 493);
|
|
2981
|
+
return target;
|
|
2982
|
+
}
|
|
2983
|
+
function writeHookSettings(settingsFile, binary, spec, dryRun) {
|
|
2984
|
+
let settings = { ...spec.settings.scaffold ?? {} };
|
|
2985
|
+
const exists = fs.existsSync(settingsFile);
|
|
2986
|
+
if (exists) {
|
|
2987
|
+
const raw = fs.readFileSync(settingsFile, "utf8").trim();
|
|
2988
|
+
if (raw) {
|
|
2989
|
+
try {
|
|
2990
|
+
settings = JSON.parse(raw);
|
|
2991
|
+
} catch {
|
|
2992
|
+
console.error(`
|
|
2993
|
+
${settingsFile} is not valid JSON. Fix or move it, then run setup again.`);
|
|
2994
|
+
return null;
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
const command = hookCommand(binary);
|
|
2999
|
+
const hooks = { ...settings.hooks ?? {} };
|
|
3000
|
+
for (const event of spec.hookEvents) {
|
|
3001
|
+
const kept = (hooks[event] ?? []).filter((entry) => !isOurs(entry, spec));
|
|
3002
|
+
hooks[event] = [...kept, spec.settings.entry(command, event)];
|
|
3003
|
+
}
|
|
3004
|
+
const updated = { ...settings, hooks };
|
|
3005
|
+
const serialised = `${JSON.stringify(updated, null, 2)}
|
|
3006
|
+
`;
|
|
3007
|
+
if (exists && fs.readFileSync(settingsFile, "utf8") === serialised)
|
|
3008
|
+
return false;
|
|
3009
|
+
if (dryRun) {
|
|
3010
|
+
console.log(`
|
|
3011
|
+
--- ${settingsFile} (dry run) ---
|
|
3012
|
+
${serialised}`);
|
|
3013
|
+
return true;
|
|
3014
|
+
}
|
|
3015
|
+
if (exists)
|
|
3016
|
+
fs.copyFileSync(settingsFile, `${settingsFile}.ascenda-backup`);
|
|
3017
|
+
fs.mkdirSync(path.dirname(settingsFile), { recursive: true });
|
|
3018
|
+
fs.writeFileSync(settingsFile, serialised, "utf8");
|
|
3019
|
+
return true;
|
|
3020
|
+
}
|
|
3021
|
+
function hookCommand(binary) {
|
|
3022
|
+
return `"${process.execPath}" "${binary}"`;
|
|
3023
|
+
}
|
|
3024
|
+
function isOurs(entry, spec) {
|
|
3025
|
+
const command = spec.settings.commandOf(entry);
|
|
3026
|
+
return typeof command === "string" && command.includes(spec.binaryName);
|
|
3027
|
+
}
|
|
3028
|
+
function findStaleHookCommands(settings, binary, spec) {
|
|
3029
|
+
const stale = /* @__PURE__ */ new Set();
|
|
3030
|
+
for (const entries of Object.values(settings.hooks ?? {})) {
|
|
3031
|
+
for (const entry of entries ?? []) {
|
|
3032
|
+
const command = spec.settings.commandOf(entry);
|
|
3033
|
+
if (typeof command !== "string")
|
|
3034
|
+
continue;
|
|
3035
|
+
if (!/ascenda/i.test(command) || command.includes(binary))
|
|
3036
|
+
continue;
|
|
3037
|
+
stale.add(command);
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
3040
|
+
return [...stale];
|
|
3041
|
+
}
|
|
3042
|
+
function readSettings(settingsFile) {
|
|
3043
|
+
try {
|
|
3044
|
+
return JSON.parse(fs.readFileSync(settingsFile, "utf8"));
|
|
3045
|
+
} catch {
|
|
3046
|
+
return {};
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
function printStatus(options, spec) {
|
|
3050
|
+
const credentials = (0, credentials_1.readHostCredentials)(spec.host);
|
|
3051
|
+
const settingsFile = spec.settings.settingsPath(options.scope, options.projectDir);
|
|
3052
|
+
const binary = cliAgentHookBinPath(spec.binaryName);
|
|
3053
|
+
const tokenFile = credentials?.toolInstallationId ? (0, tokenStore_1.defaultTokenFilePath)(credentials.toolInstallationId) : void 0;
|
|
3054
|
+
const settings = readSettings(settingsFile);
|
|
3055
|
+
const registered = spec.hookEvents.filter((event) => (settings.hooks?.[event] ?? []).some((entry) => isOurs(entry, spec))).length;
|
|
3056
|
+
const stale = findStaleHookCommands(settings, binary, spec);
|
|
3057
|
+
console.log(`api base url ${credentials?.apiBaseUrl ?? "\u2014 not configured"}`);
|
|
3058
|
+
console.log(`pairing ${credentials?.toolInstallationId ?? "\u2014 not paired"}`);
|
|
3059
|
+
console.log(`token ${tokenFile && (0, tokenStore_1.readTokenFile)(tokenFile) ? "present" : "\u2014 missing"}`);
|
|
3060
|
+
console.log(`hook binary ${fs.existsSync(binary) ? binary : "\u2014 not installed"}`);
|
|
3061
|
+
console.log(`hooks ${registered}/${spec.hookEvents.length} registered in ${settingsFile}`);
|
|
3062
|
+
if (stale.length) {
|
|
3063
|
+
console.log(`stale hooks ${stale.length} not pointing at the installed binary \u2014 each one fails silently per event:`);
|
|
3064
|
+
for (const command of stale)
|
|
3065
|
+
console.log(` ${command}`);
|
|
3066
|
+
console.log(` Remove them from ${settingsFile} by hand; setup cannot tell them from a hook you wrote.`);
|
|
3067
|
+
}
|
|
3068
|
+
const healthy = credentials?.toolInstallationId && registered === spec.hookEvents.length && fs.existsSync(binary) && !stale.length;
|
|
3069
|
+
return healthy ? 0 : 1;
|
|
3070
|
+
}
|
|
3071
|
+
function uninstall(options, spec) {
|
|
3072
|
+
const settingsFile = spec.settings.settingsPath(options.scope, options.projectDir);
|
|
3073
|
+
if (fs.existsSync(settingsFile)) {
|
|
3074
|
+
try {
|
|
3075
|
+
const settings = JSON.parse(fs.readFileSync(settingsFile, "utf8"));
|
|
3076
|
+
const hooks = { ...settings.hooks ?? {} };
|
|
3077
|
+
for (const event of Object.keys(hooks)) {
|
|
3078
|
+
const kept = hooks[event].filter((entry) => !isOurs(entry, spec));
|
|
3079
|
+
if (kept.length)
|
|
3080
|
+
hooks[event] = kept;
|
|
3081
|
+
else
|
|
3082
|
+
delete hooks[event];
|
|
3083
|
+
}
|
|
3084
|
+
const updated = { ...settings, hooks };
|
|
3085
|
+
if (!Object.keys(hooks).length)
|
|
3086
|
+
delete updated.hooks;
|
|
3087
|
+
fs.copyFileSync(settingsFile, `${settingsFile}.ascenda-backup`);
|
|
3088
|
+
fs.writeFileSync(settingsFile, `${JSON.stringify(updated, null, 2)}
|
|
3089
|
+
`, "utf8");
|
|
3090
|
+
console.log(`hooks removed from ${settingsFile}`);
|
|
3091
|
+
} catch {
|
|
3092
|
+
console.error(`could not parse ${settingsFile} \u2014 remove the ascenda hook entries by hand`);
|
|
3093
|
+
return 1;
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
const binary = cliAgentHookBinPath(spec.binaryName);
|
|
3097
|
+
if (fs.existsSync(binary)) {
|
|
3098
|
+
fs.rmSync(binary);
|
|
3099
|
+
console.log(`removed ${binary}`);
|
|
3100
|
+
}
|
|
3101
|
+
if ((0, credentials_1.readHostCredentials)(spec.host)) {
|
|
3102
|
+
(0, credentials_1.removeHostCredentials)(spec.host);
|
|
3103
|
+
console.log(`removed tools.${spec.host} from ${(0, credentials_1.credentialsFilePath)()}`);
|
|
3104
|
+
}
|
|
3105
|
+
console.log(`tokens left in ${path.join((0, tokenStore_1.ascendaHome)(), "tokens")} \u2014 revoke in the Ascenda app to invalidate them`);
|
|
3106
|
+
return 0;
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
});
|
|
3110
|
+
|
|
1671
3111
|
// ../packages/tool-kit/out/turnState.js
|
|
1672
3112
|
var require_turnState = __commonJS({
|
|
1673
3113
|
"../packages/tool-kit/out/turnState.js"(exports) {
|
|
@@ -1881,8 +3321,9 @@ var require_out2 = __commonJS({
|
|
|
1881
3321
|
"../packages/tool-kit/out/index.js"(exports) {
|
|
1882
3322
|
"use strict";
|
|
1883
3323
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1884
|
-
exports.
|
|
1885
|
-
exports.
|
|
3324
|
+
exports.consumeTurnDurationMs = exports.writeTopLevelCredentials = exports.writeMachineCredentials = exports.writeHostCredentials = exports.removeHostCredentials = exports.readMachineCredentials = exports.readHostCredentials = exports.credentialsFilePath = exports.writeHookSettings = exports.runCliAgentSetup = exports.isCliAgentManagementCommand = exports.findStaleHookCommands = exports.cliAgentHookBinPath = exports.resolveContextHashes = exports.resolveCliAgentInstallationId = exports.loadCliAgentConfig = exports.deliverHookEvents = exports.MissingInstallationIdError = exports.DEFAULT_API_BASE_URL = exports.resolveEventLogPath = exports.expandUserPath = exports.appendEventLog = exports.EVENT_LOG_ENV_VAR = exports.buildEventPayload = exports.AscendaSemanticEventError = exports.AscendaEventSender = exports.mintIdempotencyKey = exports.looksLikeCorrection = exports.outcomeForHook = exports.inferOutcome = exports.getNestedNumber = exports.getNestedString = exports.getNested = exports.getNumber = exports.getString = exports.localHourAt = exports.utcOffsetMinutesAt = exports.BUSINESS_DAY = exports.isOutsideBusinessHours = exports.isAfterHours = exports.bucketDurationMs = exports.bucketLinesChanged = exports.classifyModelClass = exports.autonomyBand = exports.invitesDebrief = exports.classifyWorkMilestone = exports.isReworkGitAction = exports.classifyGitAction = exports.isVerificationCommand = exports.classifyCommand = void 0;
|
|
3325
|
+
exports.postToolEvent = exports.renewToolToken = exports.getPairingStatus = exports.createPairingSession = exports.AscendaApiError = exports.liveBusSocketCandidates = exports.liveBusSocketPath = exports.bucketPromptSize = exports.emitLiveSignal = exports.recordForgeProjectAlias = exports.forgeFullNameFromConfig = exports.readForgeFullName = exports.parseForgeFullName = exports.forgeProjectHash = exports.workContextRegistryFilePath = exports.readWorkContextRegistry = exports.recordWorkContextAlias = exports.recordWorkContext = exports.readBranchName = exports.normalizeBranchName = exports.deriveBranchHashForCwd = exports.deriveBranchHash = exports.deriveWorkContext = exports.hashWithMachineSalt = exports.readOrCreateMachineSalt = exports.machineSaltFilePath = exports.enforceOutboxBounds = exports.claimOutbox = exports.readOutboxSummary = exports.appendToOutbox = exports.defaultOutboxFilePath = exports.outboxDrainEnabled = exports.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE = exports.DEFAULT_OUTBOX_MAX_AGE_MS = exports.DEFAULT_OUTBOX_MAX_ENTRIES = exports.OUTBOX_DRAIN_ENV_VAR = exports.recordOutboxDiscard = exports.unresolvedToolInstallationId = exports.unresolvedStateFilePath = exports.markFailureNotified = exports.shouldAnnounceFailure = exports.recordSendOutcome = exports.readCollectorState = exports.defaultStateFilePath = exports.readTokenFile = exports.persistEventWriteToken = exports.listPersistedToolInstallationIds = exports.defaultTokenFilePath = exports.ascendaHome = exports.recordTurnStart = void 0;
|
|
3326
|
+
exports.isRetryableStatus = exports.parseIngestResponse = exports.postToolEventsBatch = void 0;
|
|
1886
3327
|
var commandClassifier_1 = require_commandClassifier();
|
|
1887
3328
|
Object.defineProperty(exports, "classifyCommand", { enumerable: true, get: function() {
|
|
1888
3329
|
return commandClassifier_1.classifyCommand;
|
|
@@ -1904,6 +3345,14 @@ var require_out2 = __commonJS({
|
|
|
1904
3345
|
Object.defineProperty(exports, "invitesDebrief", { enumerable: true, get: function() {
|
|
1905
3346
|
return workMilestoneClassifier_1.invitesDebrief;
|
|
1906
3347
|
} });
|
|
3348
|
+
var autonomyBand_1 = require_autonomyBand();
|
|
3349
|
+
Object.defineProperty(exports, "autonomyBand", { enumerable: true, get: function() {
|
|
3350
|
+
return autonomyBand_1.autonomyBand;
|
|
3351
|
+
} });
|
|
3352
|
+
var modelClassifier_1 = require_modelClassifier();
|
|
3353
|
+
Object.defineProperty(exports, "classifyModelClass", { enumerable: true, get: function() {
|
|
3354
|
+
return modelClassifier_1.classifyModelClass;
|
|
3355
|
+
} });
|
|
1907
3356
|
var buckets_1 = require_buckets();
|
|
1908
3357
|
Object.defineProperty(exports, "bucketLinesChanged", { enumerable: true, get: function() {
|
|
1909
3358
|
return buckets_1.bucketLinesChanged;
|
|
@@ -1952,6 +3401,9 @@ var require_out2 = __commonJS({
|
|
|
1952
3401
|
Object.defineProperty(exports, "looksLikeCorrection", { enumerable: true, get: function() {
|
|
1953
3402
|
return payload_1.looksLikeCorrection;
|
|
1954
3403
|
} });
|
|
3404
|
+
Object.defineProperty(exports, "mintIdempotencyKey", { enumerable: true, get: function() {
|
|
3405
|
+
return payload_1.mintIdempotencyKey;
|
|
3406
|
+
} });
|
|
1955
3407
|
var eventSender_1 = require_eventSender();
|
|
1956
3408
|
Object.defineProperty(exports, "AscendaEventSender", { enumerable: true, get: function() {
|
|
1957
3409
|
return eventSender_1.AscendaEventSender;
|
|
@@ -1979,15 +3431,59 @@ var require_out2 = __commonJS({
|
|
|
1979
3431
|
Object.defineProperty(exports, "DEFAULT_API_BASE_URL", { enumerable: true, get: function() {
|
|
1980
3432
|
return hookAdapter_1.DEFAULT_API_BASE_URL;
|
|
1981
3433
|
} });
|
|
3434
|
+
Object.defineProperty(exports, "MissingInstallationIdError", { enumerable: true, get: function() {
|
|
3435
|
+
return hookAdapter_1.MissingInstallationIdError;
|
|
3436
|
+
} });
|
|
1982
3437
|
Object.defineProperty(exports, "deliverHookEvents", { enumerable: true, get: function() {
|
|
1983
3438
|
return hookAdapter_1.deliverHookEvents;
|
|
1984
3439
|
} });
|
|
1985
3440
|
Object.defineProperty(exports, "loadCliAgentConfig", { enumerable: true, get: function() {
|
|
1986
3441
|
return hookAdapter_1.loadCliAgentConfig;
|
|
1987
3442
|
} });
|
|
3443
|
+
Object.defineProperty(exports, "resolveCliAgentInstallationId", { enumerable: true, get: function() {
|
|
3444
|
+
return hookAdapter_1.resolveCliAgentInstallationId;
|
|
3445
|
+
} });
|
|
1988
3446
|
Object.defineProperty(exports, "resolveContextHashes", { enumerable: true, get: function() {
|
|
1989
3447
|
return hookAdapter_1.resolveContextHashes;
|
|
1990
3448
|
} });
|
|
3449
|
+
var cliAgentSetup_1 = require_cliAgentSetup();
|
|
3450
|
+
Object.defineProperty(exports, "cliAgentHookBinPath", { enumerable: true, get: function() {
|
|
3451
|
+
return cliAgentSetup_1.cliAgentHookBinPath;
|
|
3452
|
+
} });
|
|
3453
|
+
Object.defineProperty(exports, "findStaleHookCommands", { enumerable: true, get: function() {
|
|
3454
|
+
return cliAgentSetup_1.findStaleHookCommands;
|
|
3455
|
+
} });
|
|
3456
|
+
Object.defineProperty(exports, "isCliAgentManagementCommand", { enumerable: true, get: function() {
|
|
3457
|
+
return cliAgentSetup_1.isCliAgentManagementCommand;
|
|
3458
|
+
} });
|
|
3459
|
+
Object.defineProperty(exports, "runCliAgentSetup", { enumerable: true, get: function() {
|
|
3460
|
+
return cliAgentSetup_1.runCliAgentSetup;
|
|
3461
|
+
} });
|
|
3462
|
+
Object.defineProperty(exports, "writeHookSettings", { enumerable: true, get: function() {
|
|
3463
|
+
return cliAgentSetup_1.writeHookSettings;
|
|
3464
|
+
} });
|
|
3465
|
+
var credentials_1 = require_credentials();
|
|
3466
|
+
Object.defineProperty(exports, "credentialsFilePath", { enumerable: true, get: function() {
|
|
3467
|
+
return credentials_1.credentialsFilePath;
|
|
3468
|
+
} });
|
|
3469
|
+
Object.defineProperty(exports, "readHostCredentials", { enumerable: true, get: function() {
|
|
3470
|
+
return credentials_1.readHostCredentials;
|
|
3471
|
+
} });
|
|
3472
|
+
Object.defineProperty(exports, "readMachineCredentials", { enumerable: true, get: function() {
|
|
3473
|
+
return credentials_1.readMachineCredentials;
|
|
3474
|
+
} });
|
|
3475
|
+
Object.defineProperty(exports, "removeHostCredentials", { enumerable: true, get: function() {
|
|
3476
|
+
return credentials_1.removeHostCredentials;
|
|
3477
|
+
} });
|
|
3478
|
+
Object.defineProperty(exports, "writeHostCredentials", { enumerable: true, get: function() {
|
|
3479
|
+
return credentials_1.writeHostCredentials;
|
|
3480
|
+
} });
|
|
3481
|
+
Object.defineProperty(exports, "writeMachineCredentials", { enumerable: true, get: function() {
|
|
3482
|
+
return credentials_1.writeMachineCredentials;
|
|
3483
|
+
} });
|
|
3484
|
+
Object.defineProperty(exports, "writeTopLevelCredentials", { enumerable: true, get: function() {
|
|
3485
|
+
return credentials_1.writeTopLevelCredentials;
|
|
3486
|
+
} });
|
|
1991
3487
|
var turnState_1 = require_turnState();
|
|
1992
3488
|
Object.defineProperty(exports, "consumeTurnDurationMs", { enumerable: true, get: function() {
|
|
1993
3489
|
return turnState_1.consumeTurnDurationMs;
|
|
@@ -2002,6 +3498,9 @@ var require_out2 = __commonJS({
|
|
|
2002
3498
|
Object.defineProperty(exports, "defaultTokenFilePath", { enumerable: true, get: function() {
|
|
2003
3499
|
return tokenStore_1.defaultTokenFilePath;
|
|
2004
3500
|
} });
|
|
3501
|
+
Object.defineProperty(exports, "listPersistedToolInstallationIds", { enumerable: true, get: function() {
|
|
3502
|
+
return tokenStore_1.listPersistedToolInstallationIds;
|
|
3503
|
+
} });
|
|
2005
3504
|
Object.defineProperty(exports, "persistEventWriteToken", { enumerable: true, get: function() {
|
|
2006
3505
|
return tokenStore_1.persistEventWriteToken;
|
|
2007
3506
|
} });
|
|
@@ -2024,6 +3523,46 @@ var require_out2 = __commonJS({
|
|
|
2024
3523
|
Object.defineProperty(exports, "markFailureNotified", { enumerable: true, get: function() {
|
|
2025
3524
|
return stateStore_1.markFailureNotified;
|
|
2026
3525
|
} });
|
|
3526
|
+
Object.defineProperty(exports, "unresolvedStateFilePath", { enumerable: true, get: function() {
|
|
3527
|
+
return stateStore_1.unresolvedStateFilePath;
|
|
3528
|
+
} });
|
|
3529
|
+
Object.defineProperty(exports, "unresolvedToolInstallationId", { enumerable: true, get: function() {
|
|
3530
|
+
return stateStore_1.unresolvedToolInstallationId;
|
|
3531
|
+
} });
|
|
3532
|
+
Object.defineProperty(exports, "recordOutboxDiscard", { enumerable: true, get: function() {
|
|
3533
|
+
return stateStore_1.recordOutboxDiscard;
|
|
3534
|
+
} });
|
|
3535
|
+
var outbox_1 = require_outbox();
|
|
3536
|
+
Object.defineProperty(exports, "OUTBOX_DRAIN_ENV_VAR", { enumerable: true, get: function() {
|
|
3537
|
+
return outbox_1.OUTBOX_DRAIN_ENV_VAR;
|
|
3538
|
+
} });
|
|
3539
|
+
Object.defineProperty(exports, "DEFAULT_OUTBOX_MAX_ENTRIES", { enumerable: true, get: function() {
|
|
3540
|
+
return outbox_1.DEFAULT_OUTBOX_MAX_ENTRIES;
|
|
3541
|
+
} });
|
|
3542
|
+
Object.defineProperty(exports, "DEFAULT_OUTBOX_MAX_AGE_MS", { enumerable: true, get: function() {
|
|
3543
|
+
return outbox_1.DEFAULT_OUTBOX_MAX_AGE_MS;
|
|
3544
|
+
} });
|
|
3545
|
+
Object.defineProperty(exports, "DEFAULT_OUTBOX_DRAIN_BATCH_SIZE", { enumerable: true, get: function() {
|
|
3546
|
+
return outbox_1.DEFAULT_OUTBOX_DRAIN_BATCH_SIZE;
|
|
3547
|
+
} });
|
|
3548
|
+
Object.defineProperty(exports, "outboxDrainEnabled", { enumerable: true, get: function() {
|
|
3549
|
+
return outbox_1.outboxDrainEnabled;
|
|
3550
|
+
} });
|
|
3551
|
+
Object.defineProperty(exports, "defaultOutboxFilePath", { enumerable: true, get: function() {
|
|
3552
|
+
return outbox_1.defaultOutboxFilePath;
|
|
3553
|
+
} });
|
|
3554
|
+
Object.defineProperty(exports, "appendToOutbox", { enumerable: true, get: function() {
|
|
3555
|
+
return outbox_1.appendToOutbox;
|
|
3556
|
+
} });
|
|
3557
|
+
Object.defineProperty(exports, "readOutboxSummary", { enumerable: true, get: function() {
|
|
3558
|
+
return outbox_1.readOutboxSummary;
|
|
3559
|
+
} });
|
|
3560
|
+
Object.defineProperty(exports, "claimOutbox", { enumerable: true, get: function() {
|
|
3561
|
+
return outbox_1.claimOutbox;
|
|
3562
|
+
} });
|
|
3563
|
+
Object.defineProperty(exports, "enforceOutboxBounds", { enumerable: true, get: function() {
|
|
3564
|
+
return outbox_1.enforceOutboxBounds;
|
|
3565
|
+
} });
|
|
2027
3566
|
var salt_1 = require_salt();
|
|
2028
3567
|
Object.defineProperty(exports, "machineSaltFilePath", { enumerable: true, get: function() {
|
|
2029
3568
|
return salt_1.machineSaltFilePath;
|
|
@@ -2038,6 +3577,18 @@ var require_out2 = __commonJS({
|
|
|
2038
3577
|
Object.defineProperty(exports, "deriveWorkContext", { enumerable: true, get: function() {
|
|
2039
3578
|
return workContext_1.deriveWorkContext;
|
|
2040
3579
|
} });
|
|
3580
|
+
Object.defineProperty(exports, "deriveBranchHash", { enumerable: true, get: function() {
|
|
3581
|
+
return workContext_1.deriveBranchHash;
|
|
3582
|
+
} });
|
|
3583
|
+
Object.defineProperty(exports, "deriveBranchHashForCwd", { enumerable: true, get: function() {
|
|
3584
|
+
return workContext_1.deriveBranchHashForCwd;
|
|
3585
|
+
} });
|
|
3586
|
+
Object.defineProperty(exports, "normalizeBranchName", { enumerable: true, get: function() {
|
|
3587
|
+
return workContext_1.normalizeBranchName;
|
|
3588
|
+
} });
|
|
3589
|
+
Object.defineProperty(exports, "readBranchName", { enumerable: true, get: function() {
|
|
3590
|
+
return workContext_1.readBranchName;
|
|
3591
|
+
} });
|
|
2041
3592
|
var contextRegistry_1 = require_contextRegistry();
|
|
2042
3593
|
Object.defineProperty(exports, "recordWorkContext", { enumerable: true, get: function() {
|
|
2043
3594
|
return contextRegistry_1.recordWorkContext;
|
|
@@ -2051,6 +3602,22 @@ var require_out2 = __commonJS({
|
|
|
2051
3602
|
Object.defineProperty(exports, "workContextRegistryFilePath", { enumerable: true, get: function() {
|
|
2052
3603
|
return contextRegistry_1.workContextRegistryFilePath;
|
|
2053
3604
|
} });
|
|
3605
|
+
var forgeProject_1 = require_forgeProject();
|
|
3606
|
+
Object.defineProperty(exports, "forgeProjectHash", { enumerable: true, get: function() {
|
|
3607
|
+
return forgeProject_1.forgeProjectHash;
|
|
3608
|
+
} });
|
|
3609
|
+
Object.defineProperty(exports, "parseForgeFullName", { enumerable: true, get: function() {
|
|
3610
|
+
return forgeProject_1.parseForgeFullName;
|
|
3611
|
+
} });
|
|
3612
|
+
Object.defineProperty(exports, "readForgeFullName", { enumerable: true, get: function() {
|
|
3613
|
+
return forgeProject_1.readForgeFullName;
|
|
3614
|
+
} });
|
|
3615
|
+
Object.defineProperty(exports, "forgeFullNameFromConfig", { enumerable: true, get: function() {
|
|
3616
|
+
return forgeProject_1.forgeFullNameFromConfig;
|
|
3617
|
+
} });
|
|
3618
|
+
Object.defineProperty(exports, "recordForgeProjectAlias", { enumerable: true, get: function() {
|
|
3619
|
+
return forgeProject_1.recordForgeProjectAlias;
|
|
3620
|
+
} });
|
|
2054
3621
|
var liveBus_1 = require_liveBus();
|
|
2055
3622
|
Object.defineProperty(exports, "emitLiveSignal", { enumerable: true, get: function() {
|
|
2056
3623
|
return liveBus_1.emitLiveSignal;
|