chofex-cli 0.1.173 → 0.1.178
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/index.js +716 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,17 +24,32 @@ chofex challenge notebook
|
|
|
24
24
|
chofex challenge test --source ./shipping.js
|
|
25
25
|
chofex challenge evaluate --source ./shipping.js
|
|
26
26
|
chofex challenge ranking
|
|
27
|
+
chofex challenge init --challenge broken-agent
|
|
28
|
+
cd broken-agent && npm test
|
|
29
|
+
chofex challenge test --challenge broken-agent --source ./scheduler.js
|
|
30
|
+
chofex challenge evaluate --challenge broken-agent --source ./scheduler.js
|
|
31
|
+
chofex challenge ranking --challenge broken-agent
|
|
27
32
|
chofex confirm
|
|
33
|
+
chofex badge
|
|
34
|
+
chofex badge regenerate
|
|
28
35
|
```
|
|
29
36
|
|
|
30
37
|
`chofex update` and `chofex upgrade` are interchangeable; both update the CLI
|
|
31
38
|
to the latest published version.
|
|
32
39
|
|
|
40
|
+
Las copias instaladas también consultan npm cada vez que se inicia `chofex` e
|
|
41
|
+
instalan una versión publicada más reciente antes de ejecutar el comando. Si
|
|
42
|
+
npm o la red no están disponibles temporalmente, se continúa con la versión
|
|
43
|
+
actual. Usa `CHOFEX_AUTO_UPDATE=0` para desactivar esta comprobación.
|
|
44
|
+
|
|
33
45
|
`chofex register` collects and submits an application with full name, role,
|
|
34
46
|
optional phone number, bio, portfolio URL, shipped project, LinkedIn and GitHub
|
|
35
47
|
URLs, and Terms and Conditions. Use `--input` to submit a completed JSON
|
|
36
48
|
application.
|
|
37
|
-
|
|
49
|
+
After attendance confirmation, `chofex badge regenerate` updates the public
|
|
50
|
+
badge name, one-line description, picture, and QR destination without changing
|
|
51
|
+
the submitted application.
|
|
52
|
+
The technical challenges do not block submission, but every challenge winner must submit
|
|
38
53
|
an application before being accepted. Top results receive a direct pass; other
|
|
39
54
|
scores give organizers another review metric.
|
|
40
55
|
|
package/dist/index.js
CHANGED
|
@@ -27645,6 +27645,7 @@ var require_throttleit = __commonJS((exports, module) => {
|
|
|
27645
27645
|
|
|
27646
27646
|
// src/index.ts
|
|
27647
27647
|
import { readFileSync } from "node:fs";
|
|
27648
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
27648
27649
|
// ../../node_modules/@effect/platform-node/dist/NodeRuntime.js
|
|
27649
27650
|
var exports_NodeRuntime = {};
|
|
27650
27651
|
__export(exports_NodeRuntime, {
|
|
@@ -58552,6 +58553,7 @@ var runWith2 = (command, config) => {
|
|
|
58552
58553
|
};
|
|
58553
58554
|
// ../../packages/challenges-contract/src/index.ts
|
|
58554
58555
|
var blackBoxChallengeSlug = "black-box";
|
|
58556
|
+
var brokenAgentChallengeSlug = "broken-agent";
|
|
58555
58557
|
var challengeCatalog = [
|
|
58556
58558
|
{
|
|
58557
58559
|
slug: blackBoxChallengeSlug,
|
|
@@ -58573,21 +58575,21 @@ var challengeCatalog = [
|
|
|
58573
58575
|
solutionKind: "javascript_source"
|
|
58574
58576
|
},
|
|
58575
58577
|
{
|
|
58576
|
-
slug:
|
|
58578
|
+
slug: brokenAgentChallengeSlug,
|
|
58577
58579
|
number: 2,
|
|
58578
58580
|
code: "02",
|
|
58579
|
-
theme: "
|
|
58580
|
-
title: "The
|
|
58581
|
-
summary: "
|
|
58582
|
-
coreSkill: "
|
|
58583
|
-
format: "
|
|
58584
|
-
formatLabel: "
|
|
58581
|
+
theme: "Broken Agent",
|
|
58582
|
+
title: "The Scheduler",
|
|
58583
|
+
summary: "Take a plausible AI-generated job scheduler whose public tests already pass and harden it against production reality.",
|
|
58584
|
+
coreSkill: "Production correctness & reliability",
|
|
58585
|
+
format: "accuracy",
|
|
58586
|
+
formatLabel: "Production readiness score",
|
|
58585
58587
|
opensAt: "2026-09-25T05:00:00.000Z",
|
|
58586
58588
|
queryLimit: 0,
|
|
58587
|
-
evaluationLimit:
|
|
58588
|
-
hiddenSampleSize:
|
|
58589
|
-
playable:
|
|
58590
|
-
solutionKind: "
|
|
58589
|
+
evaluationLimit: 5,
|
|
58590
|
+
hiddenSampleSize: 100,
|
|
58591
|
+
playable: true,
|
|
58592
|
+
solutionKind: "javascript_source"
|
|
58591
58593
|
},
|
|
58592
58594
|
{
|
|
58593
58595
|
slug: "make-it-fast",
|
|
@@ -58690,7 +58692,7 @@ var formatChallengeOpeningInPeru = (opensAt) => {
|
|
|
58690
58692
|
var challengeOpeningNotice = (title, opensAt) => `${title} opens ${formatChallengeOpeningInPeru(opensAt)}. Queries and evaluations are disabled until then; no attempts will be consumed.`;
|
|
58691
58693
|
var ChallengeSlugSchema = exports_Schema.Literals([
|
|
58692
58694
|
"black-box",
|
|
58693
|
-
"
|
|
58695
|
+
"broken-agent",
|
|
58694
58696
|
"make-it-fast",
|
|
58695
58697
|
"power-grid",
|
|
58696
58698
|
"agent-arena"
|
|
@@ -58718,7 +58720,38 @@ var ChallengeScoreSchema = exports_Schema.Struct({
|
|
|
58718
58720
|
sampleSize: exports_Schema.Number,
|
|
58719
58721
|
meanError: exports_Schema.Number,
|
|
58720
58722
|
queriesUsed: exports_Schema.Number,
|
|
58721
|
-
runtimeMs: exports_Schema.Number
|
|
58723
|
+
runtimeMs: exports_Schema.Number,
|
|
58724
|
+
evaluationsUsed: exports_Schema.optional(exports_Schema.Number),
|
|
58725
|
+
breakdown: exports_Schema.optional(exports_Schema.Struct({
|
|
58726
|
+
coreBehavior: exports_Schema.Struct({
|
|
58727
|
+
earned: exports_Schema.Number,
|
|
58728
|
+
available: exports_Schema.Number
|
|
58729
|
+
}),
|
|
58730
|
+
persistence: exports_Schema.Struct({
|
|
58731
|
+
earned: exports_Schema.Number,
|
|
58732
|
+
available: exports_Schema.Number
|
|
58733
|
+
}),
|
|
58734
|
+
concurrency: exports_Schema.Struct({
|
|
58735
|
+
earned: exports_Schema.Number,
|
|
58736
|
+
available: exports_Schema.Number
|
|
58737
|
+
}),
|
|
58738
|
+
failureRecovery: exports_Schema.Struct({
|
|
58739
|
+
earned: exports_Schema.Number,
|
|
58740
|
+
available: exports_Schema.Number
|
|
58741
|
+
}),
|
|
58742
|
+
idempotency: exports_Schema.Struct({
|
|
58743
|
+
earned: exports_Schema.Number,
|
|
58744
|
+
available: exports_Schema.Number
|
|
58745
|
+
}),
|
|
58746
|
+
regressionSafety: exports_Schema.Struct({
|
|
58747
|
+
earned: exports_Schema.Number,
|
|
58748
|
+
available: exports_Schema.Number
|
|
58749
|
+
}),
|
|
58750
|
+
performance: exports_Schema.Struct({
|
|
58751
|
+
earned: exports_Schema.Number,
|
|
58752
|
+
available: exports_Schema.Number
|
|
58753
|
+
})
|
|
58754
|
+
}))
|
|
58722
58755
|
});
|
|
58723
58756
|
var ChallengeProgressStatus = exports_Schema.Literals([
|
|
58724
58757
|
"not_started",
|
|
@@ -58785,7 +58818,8 @@ var ChallengeEvaluationSummarySchema = exports_Schema.Struct({
|
|
|
58785
58818
|
shareCode: exports_Schema.String,
|
|
58786
58819
|
rank: exports_Schema.optional(exports_Schema.Number),
|
|
58787
58820
|
percentile: exports_Schema.optional(exports_Schema.Number),
|
|
58788
|
-
createdAt: exports_Schema.String
|
|
58821
|
+
createdAt: exports_Schema.String,
|
|
58822
|
+
breakdown: exports_Schema.optional(ChallengeScoreSchema.fields.breakdown)
|
|
58789
58823
|
});
|
|
58790
58824
|
var ChallengeAttemptViewSchema = exports_Schema.Struct({
|
|
58791
58825
|
challenge: ChallengeCatalogItemSchema,
|
|
@@ -58802,6 +58836,7 @@ var ChallengeQueryResultSchema = exports_Schema.Struct({
|
|
|
58802
58836
|
queriesLimit: exports_Schema.Number
|
|
58803
58837
|
});
|
|
58804
58838
|
var ChallengeLocalTestResultSchema = exports_Schema.Struct({
|
|
58839
|
+
kind: exports_Schema.optional(exports_Schema.Literals(["black_box", "broken_agent"])),
|
|
58805
58840
|
matchedObservations: exports_Schema.Number,
|
|
58806
58841
|
observationCount: exports_Schema.Number,
|
|
58807
58842
|
accuracy: exports_Schema.Number,
|
|
@@ -58827,7 +58862,8 @@ var ChallengeEvaluationResultSchema = exports_Schema.Struct({
|
|
|
58827
58862
|
evaluationsRemaining: exports_Schema.Number,
|
|
58828
58863
|
evaluationsLimit: exports_Schema.Number,
|
|
58829
58864
|
rankingPath: exports_Schema.String,
|
|
58830
|
-
shareText: exports_Schema.String
|
|
58865
|
+
shareText: exports_Schema.String,
|
|
58866
|
+
breakdown: exports_Schema.optional(ChallengeScoreSchema.fields.breakdown)
|
|
58831
58867
|
});
|
|
58832
58868
|
var ChallengeRankingEntrySchema = exports_Schema.Struct({
|
|
58833
58869
|
rank: exports_Schema.Number,
|
|
@@ -59156,10 +59192,25 @@ var BadgeStatus = exports_Schema.Literals([
|
|
|
59156
59192
|
"completed",
|
|
59157
59193
|
"failed"
|
|
59158
59194
|
]);
|
|
59195
|
+
var BadgeProfileSchema = exports_Schema.Struct({
|
|
59196
|
+
fullName: nonBlank(200),
|
|
59197
|
+
oneLiner: nonBlank(30),
|
|
59198
|
+
linkUrl: url,
|
|
59199
|
+
placement: exports_Schema.String
|
|
59200
|
+
});
|
|
59159
59201
|
var BadgeResultSchema = exports_Schema.Struct({
|
|
59160
59202
|
status: BadgeStatus,
|
|
59161
|
-
url: exports_Schema.optional(exports_Schema.String)
|
|
59203
|
+
url: exports_Schema.optional(exports_Schema.String),
|
|
59204
|
+
profile: exports_Schema.optional(BadgeProfileSchema)
|
|
59162
59205
|
});
|
|
59206
|
+
var badgeRegenerationInputFields = {
|
|
59207
|
+
fullName: nonBlank(200),
|
|
59208
|
+
oneLiner: nonBlank(30),
|
|
59209
|
+
linkUrl: url,
|
|
59210
|
+
pictureSource: exports_Schema.optional(PictureSource)
|
|
59211
|
+
};
|
|
59212
|
+
var BadgeRegenerationInput = exports_Schema.Struct(badgeRegenerationInputFields);
|
|
59213
|
+
var badgeRegenerationInputFieldNames = Object.keys(badgeRegenerationInputFields);
|
|
59163
59214
|
var PictureUploadSchema = exports_Schema.Struct({
|
|
59164
59215
|
url: exports_Schema.String,
|
|
59165
59216
|
contentType: PictureContentType,
|
|
@@ -59697,6 +59748,7 @@ var register = (options, input) => request3(options, "/api/v1/registrations", {
|
|
|
59697
59748
|
var getCurrentUser = (options) => request3(options, "/api/v1/me", { method: "GET" }, decodeCurrentUser);
|
|
59698
59749
|
var getRegistration = (options) => request3(options, "/api/v1/registration", { method: "GET" }, decodeRegistrationResult);
|
|
59699
59750
|
var getBadge = (options) => request3(options, "/api/v1/badge", { method: "GET" }, decodeBadgeResult);
|
|
59751
|
+
var regenerateBadge = (options, input) => request3(options, "/api/v1/badge", { method: "PATCH", body: JSON.stringify(input) }, decodeBadgeResult);
|
|
59700
59752
|
var confirmAttendance = (options, input) => request3(options, "/api/v1/registration/attendance", { method: "PUT", body: JSON.stringify(input) }, decodeRegistrationResult);
|
|
59701
59753
|
var beginPictureUpload = (options, input) => request3(options, "/api/v1/profile-picture", { method: "POST", body: JSON.stringify(input) }, decodePictureUploadGrant);
|
|
59702
59754
|
var completePictureUpload = (options, input) => request3(options, "/api/v1/profile-picture", { method: "PUT", body: JSON.stringify(input) }, decodePictureUpload);
|
|
@@ -59709,6 +59761,7 @@ var getChallengeRanking = (options, slug) => publicRequest(options, `/api/v1/cha
|
|
|
59709
59761
|
|
|
59710
59762
|
// src/challenge-input.ts
|
|
59711
59763
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
59764
|
+
var defaultChallengeSlug = "black-box";
|
|
59712
59765
|
var readStdin = async () => {
|
|
59713
59766
|
const chunks = [];
|
|
59714
59767
|
for await (const chunk of process.stdin) {
|
|
@@ -59724,9 +59777,12 @@ var readTextFile = (path4) => exports_Effect.tryPromise({
|
|
|
59724
59777
|
},
|
|
59725
59778
|
catch: (error2) => cliError("INVALID_INPUT_FILE", `Could not read ${path4}: ${String(error2)}`)
|
|
59726
59779
|
});
|
|
59727
|
-
var javascriptSourceFromPath = (path4) => {
|
|
59780
|
+
var javascriptSourceFromPath = (path4, challenge = defaultChallengeSlug) => {
|
|
59728
59781
|
if (!path4) {
|
|
59729
|
-
|
|
59782
|
+
let expectedFunction = "calculateShipping(input)";
|
|
59783
|
+
if (challenge === "broken-agent")
|
|
59784
|
+
expectedFunction = "createScheduler(dependencies)";
|
|
59785
|
+
return exports_Effect.fail(cliError("SOURCE_REQUIRED", `Pass --source <file.js> with function ${expectedFunction}`));
|
|
59730
59786
|
}
|
|
59731
59787
|
return readTextFile(path4).pipe(exports_Effect.map((source) => ({ kind: "javascript_source", source })));
|
|
59732
59788
|
};
|
|
@@ -59778,7 +59834,6 @@ var shipmentInput = (path4, flags) => {
|
|
|
59778
59834
|
}
|
|
59779
59835
|
return interactiveShipment();
|
|
59780
59836
|
};
|
|
59781
|
-
var defaultChallengeSlug = "black-box";
|
|
59782
59837
|
|
|
59783
59838
|
// src/brand.ts
|
|
59784
59839
|
var eventName = "Hack the Andes";
|
|
@@ -59834,6 +59889,32 @@ var challengeShowText = (attempt) => {
|
|
|
59834
59889
|
const { challenge, progress } = attempt;
|
|
59835
59890
|
const queriesRemaining = progress.queriesLimit - progress.queriesUsed;
|
|
59836
59891
|
const evaluationsRemaining = progress.evaluationsLimit - progress.evaluationsUsed;
|
|
59892
|
+
if (challenge.slug === "broken-agent") {
|
|
59893
|
+
let caseStatus2 = "READY TO AUDIT";
|
|
59894
|
+
if (attempt.latestEvaluation)
|
|
59895
|
+
caseStatus2 = "EVALUATED";
|
|
59896
|
+
const lines3 = [
|
|
59897
|
+
`${challenge.title.toUpperCase()} — CASE #${challenge.code}`,
|
|
59898
|
+
challenge.summary,
|
|
59899
|
+
"",
|
|
59900
|
+
`CASE STATUS: ${caseStatus2}`,
|
|
59901
|
+
"",
|
|
59902
|
+
"The public tests are green. Your job is to make the scheduler trustworthy under production conditions.",
|
|
59903
|
+
"AI tools are allowed.",
|
|
59904
|
+
"",
|
|
59905
|
+
`Evaluations ${evaluationsRemaining} / ${progress.evaluationsLimit} remaining`
|
|
59906
|
+
];
|
|
59907
|
+
if (progress.bestAccuracy !== undefined) {
|
|
59908
|
+
lines3.push("", `Best score ${percent(progress.bestAccuracy)}`);
|
|
59909
|
+
if (progress.rank !== undefined)
|
|
59910
|
+
lines3.push(`Rank #${progress.rank}`);
|
|
59911
|
+
if (progress.shareCode)
|
|
59912
|
+
lines3.push(`Share code #${progress.shareCode}`);
|
|
59913
|
+
}
|
|
59914
|
+
lines3.push("", "YOUR NEXT MOVE", "Read the contract, audit scheduler.js, and keep the visible suite green.", " cd broken-agent && npm test", " chofex challenge test --challenge broken-agent --source ./broken-agent/scheduler.js");
|
|
59915
|
+
return lines3.join(`
|
|
59916
|
+
`);
|
|
59917
|
+
}
|
|
59837
59918
|
let evidence = `${attempt.observations.length} observations`;
|
|
59838
59919
|
if (attempt.observations.length === 1)
|
|
59839
59920
|
evidence = "1 observation";
|
|
@@ -59996,6 +60077,26 @@ var notebookCsvText = (observations) => {
|
|
|
59996
60077
|
`);
|
|
59997
60078
|
};
|
|
59998
60079
|
var challengeTestText = (result3) => {
|
|
60080
|
+
if (result3.kind === "broken_agent") {
|
|
60081
|
+
const lines3 = [
|
|
60082
|
+
"PUBLIC SUITE — BROKEN AGENT",
|
|
60083
|
+
`${result3.matchedObservations} / ${result3.observationCount} visible behaviors passing`
|
|
60084
|
+
];
|
|
60085
|
+
if (result3.accuracy === 1) {
|
|
60086
|
+
lines3.push("", "Everything passes.", "Unfortunately, that does not mean the scheduler is production-correct.", "Reason about concurrency, restarts, failures, and idempotency before evaluating.", "", "Next: spend one official evaluation when you would ship it", " chofex challenge evaluate --challenge broken-agent --source ./broken-agent/scheduler.js");
|
|
60087
|
+
return lines3.join(`
|
|
60088
|
+
`);
|
|
60089
|
+
}
|
|
60090
|
+
if (result3.mismatches.length > 0) {
|
|
60091
|
+
lines3.push("", "Visible failures:");
|
|
60092
|
+
for (const mismatch of result3.mismatches) {
|
|
60093
|
+
lines3.push(` ${String(mismatch.actual)}`);
|
|
60094
|
+
}
|
|
60095
|
+
}
|
|
60096
|
+
lines3.push("", "Fix the public regressions before using an official evaluation.");
|
|
60097
|
+
return lines3.join(`
|
|
60098
|
+
`);
|
|
60099
|
+
}
|
|
59999
60100
|
let verdict = "KEEP WORKING";
|
|
60000
60101
|
if (result3.accuracy === 1)
|
|
60001
60102
|
verdict = "NOTEBOOK MATCHED";
|
|
@@ -60022,6 +60123,34 @@ var challengeTestText = (result3) => {
|
|
|
60022
60123
|
`);
|
|
60023
60124
|
};
|
|
60024
60125
|
var challengeEvaluateText = (result3) => {
|
|
60126
|
+
if (result3.breakdown) {
|
|
60127
|
+
const capabilityLines = [
|
|
60128
|
+
["Core behavior", result3.breakdown.coreBehavior],
|
|
60129
|
+
["Persistence", result3.breakdown.persistence],
|
|
60130
|
+
["Concurrency", result3.breakdown.concurrency],
|
|
60131
|
+
["Failure recovery", result3.breakdown.failureRecovery],
|
|
60132
|
+
["Idempotency", result3.breakdown.idempotency],
|
|
60133
|
+
["Regression safety", result3.breakdown.regressionSafety],
|
|
60134
|
+
["Performance", result3.breakdown.performance]
|
|
60135
|
+
];
|
|
60136
|
+
const lines3 = [
|
|
60137
|
+
"OFFICIAL VERDICT — BROKEN AGENT — PRODUCTION READINESS",
|
|
60138
|
+
`Score ${(result3.accuracy * 100).toFixed(2)} / ${result3.sampleSize}`,
|
|
60139
|
+
`Runtime ${result3.runtimeMs} ms`,
|
|
60140
|
+
"",
|
|
60141
|
+
"Capability scores",
|
|
60142
|
+
...capabilityLines.map(([label, score]) => `${label.padEnd(20)}${score.earned.toFixed(2)} / ${score.available}`)
|
|
60143
|
+
];
|
|
60144
|
+
if (result3.rank !== undefined) {
|
|
60145
|
+
lines3.push(`Rank #${result3.rank}`);
|
|
60146
|
+
}
|
|
60147
|
+
lines3.push(`Official evaluations remaining ${result3.evaluationsRemaining} / ${result3.evaluationsLimit}`, "", result3.shareText, "", "Next: inspect the leaderboard", " chofex challenge ranking --challenge broken-agent");
|
|
60148
|
+
if (result3.evaluationsRemaining > 0) {
|
|
60149
|
+
lines3.push("", "The evaluator reports capabilities, not individual hidden cases. Reason before submitting again.", " chofex challenge test --challenge broken-agent --source ./broken-agent/scheduler.js");
|
|
60150
|
+
}
|
|
60151
|
+
return lines3.join(`
|
|
60152
|
+
`);
|
|
60153
|
+
}
|
|
60025
60154
|
const lines2 = [
|
|
60026
60155
|
"OFFICIAL VERDICT — BLACK BOX REPLICATION",
|
|
60027
60156
|
`Accuracy ${percent(result3.accuracy)}`,
|
|
@@ -60050,6 +60179,18 @@ var challengeRankingText = (ranking, now3 = new Date) => {
|
|
|
60050
60179
|
if (ranking.entries.length === 0) {
|
|
60051
60180
|
lines2.push("No official evaluations yet.");
|
|
60052
60181
|
return lines2.join(`
|
|
60182
|
+
`);
|
|
60183
|
+
}
|
|
60184
|
+
if (ranking.challenge.slug === "broken-agent") {
|
|
60185
|
+
lines2.push("Rank Score Points Runtime Name");
|
|
60186
|
+
for (const entry of ranking.entries.slice(0, 20)) {
|
|
60187
|
+
const rank = String(entry.rank).padStart(4, " ");
|
|
60188
|
+
const accuracy = percent(entry.accuracy).padStart(8, " ");
|
|
60189
|
+
const points = `${entry.exactCount}/${entry.sampleSize}`.padStart(11, " ");
|
|
60190
|
+
const runtime = `${entry.runtimeMs}ms`.padStart(8, " ");
|
|
60191
|
+
lines2.push(`${rank} ${accuracy} ${points} ${runtime} ${entry.displayName} #${entry.shareCode}`);
|
|
60192
|
+
}
|
|
60193
|
+
return lines2.join(`
|
|
60053
60194
|
`);
|
|
60054
60195
|
}
|
|
60055
60196
|
lines2.push("Rank Accuracy Exact Queries Name");
|
|
@@ -60086,7 +60227,216 @@ var registrationPartsText = (result3) => {
|
|
|
60086
60227
|
};
|
|
60087
60228
|
|
|
60088
60229
|
// src/challenge-scaffold.ts
|
|
60089
|
-
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
60230
|
+
import { mkdir as mkdir2, writeFile as writeFile3 } from "node:fs/promises";
|
|
60231
|
+
|
|
60232
|
+
// ../../packages/challenges-contract/src/broken-agent.ts
|
|
60233
|
+
var brokenAgentScaffoldDirectory = "broken-agent";
|
|
60234
|
+
var brokenAgentSolutionPath = `${brokenAgentScaffoldDirectory}/scheduler.js`;
|
|
60235
|
+
var brokenAgentPackageJson = `${JSON.stringify({
|
|
60236
|
+
name: "broken-agent-challenge",
|
|
60237
|
+
private: true,
|
|
60238
|
+
type: "commonjs",
|
|
60239
|
+
scripts: { test: "node --test scheduler.test.js" }
|
|
60240
|
+
}, null, 2)}
|
|
60241
|
+
`;
|
|
60242
|
+
var brokenAgentStarterSource = `/**
|
|
60243
|
+
* Broken Agent — The Scheduler
|
|
60244
|
+
*
|
|
60245
|
+
* A coding agent implemented this scheduler and declared the feature complete.
|
|
60246
|
+
* Every public test passes. The implementation is not production-correct.
|
|
60247
|
+
* Keep the createScheduler interface intact and harden the implementation.
|
|
60248
|
+
*/
|
|
60249
|
+
function createScheduler({ store, clock, execute }) {
|
|
60250
|
+
return {
|
|
60251
|
+
async schedule(input) {
|
|
60252
|
+
const job = { ...input, status: "pending" };
|
|
60253
|
+
await store.transaction((tx) => tx.put(job));
|
|
60254
|
+
return job;
|
|
60255
|
+
},
|
|
60256
|
+
|
|
60257
|
+
async cancel(id) {
|
|
60258
|
+
return store.transaction((tx) => {
|
|
60259
|
+
const job = tx.get(id);
|
|
60260
|
+
if (!job || job.status !== "pending") return false;
|
|
60261
|
+
tx.put({ ...job, status: "cancelled" });
|
|
60262
|
+
return true;
|
|
60263
|
+
});
|
|
60264
|
+
},
|
|
60265
|
+
|
|
60266
|
+
async list() {
|
|
60267
|
+
return store.transaction((tx) => tx.list());
|
|
60268
|
+
},
|
|
60269
|
+
|
|
60270
|
+
async runDue() {
|
|
60271
|
+
const now = clock.now().getTime();
|
|
60272
|
+
const jobs = await store.transaction((tx) => tx.list());
|
|
60273
|
+
for (const job of jobs) {
|
|
60274
|
+
if (job.status !== "pending" || Date.parse(job.runAt) > now) continue;
|
|
60275
|
+
await execute(job);
|
|
60276
|
+
await store.transaction((tx) =>
|
|
60277
|
+
tx.put({ ...job, status: "completed" }),
|
|
60278
|
+
);
|
|
60279
|
+
}
|
|
60280
|
+
},
|
|
60281
|
+
};
|
|
60282
|
+
}
|
|
60283
|
+
|
|
60284
|
+
module.exports = { createScheduler };
|
|
60285
|
+
`;
|
|
60286
|
+
var brokenAgentReadme = `# Broken Agent — The Scheduler
|
|
60287
|
+
|
|
60288
|
+
> A coding agent was asked to implement a feature. It says it is done. It is
|
|
60289
|
+
> not. Your job is to ship it.
|
|
60290
|
+
|
|
60291
|
+
The repository starts with all public tests passing. Repair \`scheduler.js\`
|
|
60292
|
+
without changing its exported \`createScheduler(dependencies)\` interface.
|
|
60293
|
+
|
|
60294
|
+
## Commands
|
|
60295
|
+
|
|
60296
|
+
\`\`\`sh
|
|
60297
|
+
npm test
|
|
60298
|
+
chofex challenge test --challenge broken-agent --source ./broken-agent/scheduler.js
|
|
60299
|
+
chofex challenge evaluate --challenge broken-agent --source ./broken-agent/scheduler.js
|
|
60300
|
+
\`\`\`
|
|
60301
|
+
|
|
60302
|
+
Local and public tests are unlimited. You have **5 official evaluations**
|
|
60303
|
+
against hidden production scenarios. AI tools are explicitly allowed.
|
|
60304
|
+
|
|
60305
|
+
## Public contract
|
|
60306
|
+
|
|
60307
|
+
\`createScheduler({ store, clock, execute, workerId })\` returns:
|
|
60308
|
+
|
|
60309
|
+
- \`schedule({ id, runAt, payload })\`
|
|
60310
|
+
- \`cancel(id)\`
|
|
60311
|
+
- \`list()\`
|
|
60312
|
+
- \`runDue()\`
|
|
60313
|
+
|
|
60314
|
+
### Jobs
|
|
60315
|
+
|
|
60316
|
+
- \`id\` matches \`^[A-Za-z0-9_-]{1,64}$\`.
|
|
60317
|
+
- \`runAt\` is an ISO-8601 timestamp with an explicit timezone.
|
|
60318
|
+
- \`payload\` is JSON-serializable.
|
|
60319
|
+
- Scheduling an identical job ID is idempotent. Reusing an ID for different
|
|
60320
|
+
work must reject without changing the original job.
|
|
60321
|
+
- Past timestamps are valid and become due immediately.
|
|
60322
|
+
- \`list()\` returns jobs ordered by \`runAt\`, then \`id\`.
|
|
60323
|
+
|
|
60324
|
+
### Durability and concurrency
|
|
60325
|
+
|
|
60326
|
+
- The supplied store survives scheduler instances and process restarts.
|
|
60327
|
+
- Several workers may call \`runDue()\` concurrently against the same store.
|
|
60328
|
+
- A worker claim lasts 30 seconds. Another worker may reclaim the job when
|
|
60329
|
+
\`clock.now()\` reaches that lease deadline.
|
|
60330
|
+
- A pending job may be cancelled. A running or terminal job may not.
|
|
60331
|
+
- Failed executions retry, without preventing other due jobs from running.
|
|
60332
|
+
- A job becomes \`failed\` after 3 unsuccessful attempts.
|
|
60333
|
+
- The execution adapter applies effects idempotently by job ID. A worker may
|
|
60334
|
+
stop after the effect is applied but before completion is recorded; retrying
|
|
60335
|
+
must eventually complete the job without duplicating the effect.
|
|
60336
|
+
|
|
60337
|
+
The store exposes only \`transaction(action)\`. Inside an action, \`tx\`
|
|
60338
|
+
provides synchronous \`get(id)\`, \`put(job)\`, \`delete(id)\`, and \`list()\`
|
|
60339
|
+
operations. Transactions are serialized. Do not keep a transaction open while
|
|
60340
|
+
executing a job.
|
|
60341
|
+
|
|
60342
|
+
\`clock.now()\` returns a \`Date\`. \`execute(job)\` returns a promise.
|
|
60343
|
+
|
|
60344
|
+
## Evaluation
|
|
60345
|
+
|
|
60346
|
+
The hidden evaluator checks the published contract under deterministic
|
|
60347
|
+
concurrency, restart, failure, idempotency, compatibility, and load scenarios.
|
|
60348
|
+
It reports capability-level scores, not individual hidden-test failures.
|
|
60349
|
+
|
|
60350
|
+
- Core behavior: 10 points
|
|
60351
|
+
- Persistence: 15 points
|
|
60352
|
+
- Concurrency: 20 points
|
|
60353
|
+
- Failure recovery: 20 points
|
|
60354
|
+
- Idempotency: 15 points
|
|
60355
|
+
- Regression safety: 15 points
|
|
60356
|
+
- Performance: 5 points, available only when the load jobs complete correctly
|
|
60357
|
+
|
|
60358
|
+
Ranking order is total score, fewer official evaluations used, runtime, then
|
|
60359
|
+
official submission time. Submission time is only the final tie-breaker.
|
|
60360
|
+
`;
|
|
60361
|
+
var brokenAgentPublicTestSource = `const test = require("node:test");
|
|
60362
|
+
const assert = require("node:assert/strict");
|
|
60363
|
+
const { createScheduler } = require("./scheduler.js");
|
|
60364
|
+
|
|
60365
|
+
const clone = (value) => {
|
|
60366
|
+
if (value === undefined) return undefined;
|
|
60367
|
+
return JSON.parse(JSON.stringify(value));
|
|
60368
|
+
};
|
|
60369
|
+
|
|
60370
|
+
class MemoryStore {
|
|
60371
|
+
constructor() {
|
|
60372
|
+
this.jobs = new Map();
|
|
60373
|
+
this.tail = Promise.resolve();
|
|
60374
|
+
}
|
|
60375
|
+
|
|
60376
|
+
transaction(action) {
|
|
60377
|
+
const run = this.tail.then(() => action({
|
|
60378
|
+
get: (id) => clone(this.jobs.get(id)),
|
|
60379
|
+
put: (job) => {
|
|
60380
|
+
this.jobs.set(job.id, clone(job));
|
|
60381
|
+
return clone(job);
|
|
60382
|
+
},
|
|
60383
|
+
delete: (id) => this.jobs.delete(id),
|
|
60384
|
+
list: () => [...this.jobs.values()].map(clone),
|
|
60385
|
+
}));
|
|
60386
|
+
this.tail = run.then(() => undefined, () => undefined);
|
|
60387
|
+
return run;
|
|
60388
|
+
}
|
|
60389
|
+
}
|
|
60390
|
+
|
|
60391
|
+
const setup = () => {
|
|
60392
|
+
const store = new MemoryStore();
|
|
60393
|
+
const now = new Date("2026-10-17T15:00:00.000Z");
|
|
60394
|
+
const executed = [];
|
|
60395
|
+
const scheduler = createScheduler({
|
|
60396
|
+
store,
|
|
60397
|
+
clock: { now: () => new Date(now) },
|
|
60398
|
+
execute: async (job) => executed.push(job.id),
|
|
60399
|
+
workerId: "public-worker",
|
|
60400
|
+
});
|
|
60401
|
+
return { store, scheduler, executed };
|
|
60402
|
+
};
|
|
60403
|
+
|
|
60404
|
+
const job = (id, runAt = "2026-10-17T15:00:00.000Z") => ({
|
|
60405
|
+
id,
|
|
60406
|
+
runAt,
|
|
60407
|
+
payload: { message: id },
|
|
60408
|
+
});
|
|
60409
|
+
|
|
60410
|
+
test("schedules and lists a job", async () => {
|
|
60411
|
+
const { scheduler } = setup();
|
|
60412
|
+
await scheduler.schedule(job("job-1"));
|
|
60413
|
+
assert.equal((await scheduler.list()).length, 1);
|
|
60414
|
+
});
|
|
60415
|
+
|
|
60416
|
+
test("executes a due job", async () => {
|
|
60417
|
+
const { scheduler, executed } = setup();
|
|
60418
|
+
await scheduler.schedule(job("job-1"));
|
|
60419
|
+
await scheduler.runDue();
|
|
60420
|
+
assert.deepEqual(executed, ["job-1"]);
|
|
60421
|
+
});
|
|
60422
|
+
|
|
60423
|
+
test("does not execute a future job", async () => {
|
|
60424
|
+
const { scheduler, executed } = setup();
|
|
60425
|
+
await scheduler.schedule(job("future", "2026-10-17T16:00:00.000Z"));
|
|
60426
|
+
await scheduler.runDue();
|
|
60427
|
+
assert.deepEqual(executed, []);
|
|
60428
|
+
});
|
|
60429
|
+
|
|
60430
|
+
test("cancels a pending job", async () => {
|
|
60431
|
+
const { scheduler, executed } = setup();
|
|
60432
|
+
await scheduler.schedule(job("cancel-me"));
|
|
60433
|
+
assert.equal(await scheduler.cancel("cancel-me"), true);
|
|
60434
|
+
await scheduler.runDue();
|
|
60435
|
+
assert.deepEqual(executed, []);
|
|
60436
|
+
});
|
|
60437
|
+
`;
|
|
60438
|
+
|
|
60439
|
+
// src/challenge-scaffold.ts
|
|
60090
60440
|
var solutionPath = "shipping.js";
|
|
60091
60441
|
var starterSource = `/**
|
|
60092
60442
|
* The Shipping Machine
|
|
@@ -60107,7 +60457,36 @@ function calculateShipping(input) {
|
|
|
60107
60457
|
return 0;
|
|
60108
60458
|
}
|
|
60109
60459
|
`;
|
|
60110
|
-
var createChallengeScaffold = exports_Effect.fn("createChallengeScaffold")(function* () {
|
|
60460
|
+
var createChallengeScaffold = exports_Effect.fn("createChallengeScaffold")(function* (challengeSlug = "black-box") {
|
|
60461
|
+
const challenge = challengeBySlug(challengeSlug);
|
|
60462
|
+
if (!challenge?.playable) {
|
|
60463
|
+
return yield* exports_Effect.fail(cliError("CHALLENGE_NOT_AVAILABLE", `Challenge ${challengeSlug} is not available`));
|
|
60464
|
+
}
|
|
60465
|
+
if (challengeSlug === "broken-agent") {
|
|
60466
|
+
const status2 = yield* exports_Effect.tryPromise({
|
|
60467
|
+
try: async () => {
|
|
60468
|
+
await mkdir2(brokenAgentScaffoldDirectory);
|
|
60469
|
+
await Promise.all([
|
|
60470
|
+
writeFile3(brokenAgentSolutionPath, brokenAgentStarterSource, "utf8"),
|
|
60471
|
+
writeFile3(`${brokenAgentScaffoldDirectory}/scheduler.test.js`, brokenAgentPublicTestSource, "utf8"),
|
|
60472
|
+
writeFile3(`${brokenAgentScaffoldDirectory}/README.md`, brokenAgentReadme, "utf8"),
|
|
60473
|
+
writeFile3(`${brokenAgentScaffoldDirectory}/package.json`, brokenAgentPackageJson, "utf8")
|
|
60474
|
+
]);
|
|
60475
|
+
return "created";
|
|
60476
|
+
},
|
|
60477
|
+
catch: (error2) => error2
|
|
60478
|
+
}).pipe(exports_Effect.catch((error2) => {
|
|
60479
|
+
if (exports_Predicate.hasProperty(error2, "code") && error2.code === "EEXIST") {
|
|
60480
|
+
return exports_Effect.succeed("exists");
|
|
60481
|
+
}
|
|
60482
|
+
return exports_Effect.fail(cliError("SCAFFOLD_FAILED", `Could not create ${brokenAgentScaffoldDirectory}: ${String(error2)}`));
|
|
60483
|
+
}));
|
|
60484
|
+
return {
|
|
60485
|
+
challenge: challengeSlug,
|
|
60486
|
+
path: brokenAgentScaffoldDirectory,
|
|
60487
|
+
status: status2
|
|
60488
|
+
};
|
|
60489
|
+
}
|
|
60111
60490
|
const status = yield* exports_Effect.tryPromise({
|
|
60112
60491
|
try: async () => {
|
|
60113
60492
|
await writeFile3(solutionPath, starterSource, {
|
|
@@ -60123,14 +60502,19 @@ var createChallengeScaffold = exports_Effect.fn("createChallengeScaffold")(funct
|
|
|
60123
60502
|
}
|
|
60124
60503
|
return exports_Effect.fail(cliError("SCAFFOLD_FAILED", `Could not create ${solutionPath}: ${String(error2)}`));
|
|
60125
60504
|
}));
|
|
60126
|
-
return { path: solutionPath, status };
|
|
60505
|
+
return { challenge: challengeSlug, path: solutionPath, status };
|
|
60127
60506
|
});
|
|
60128
60507
|
|
|
60129
60508
|
// src/cli-root.ts
|
|
60509
|
+
var rootValueFlagNames = {
|
|
60510
|
+
apiUrl: "api-url",
|
|
60511
|
+
output: "output",
|
|
60512
|
+
token: "token"
|
|
60513
|
+
};
|
|
60130
60514
|
var root = exports_Command.make("chofex").pipe(exports_Command.withSharedFlags({
|
|
60131
|
-
apiUrl: exports_Flag.string(
|
|
60132
|
-
output: exports_Flag.choice(
|
|
60133
|
-
token: exports_Flag.string(
|
|
60515
|
+
apiUrl: exports_Flag.string(rootValueFlagNames.apiUrl).pipe(exports_Flag.withDefault(config.apiUrl), exports_Flag.withDescription("Chofex API base URL")),
|
|
60516
|
+
output: exports_Flag.choice(rootValueFlagNames.output, ["human", "json"]).pipe(exports_Flag.withDefault("human"), exports_Flag.withDescription("Output format")),
|
|
60517
|
+
token: exports_Flag.string(rootValueFlagNames.token).pipe(exports_Flag.optional, exports_Flag.withDescription("Clerk OAuth token (prefer CHOFEX_TOKEN to avoid shell history)"))
|
|
60134
60518
|
}), exports_Command.withDescription(`Register for and manage your ${eventName} application`));
|
|
60135
60519
|
|
|
60136
60520
|
// src/output.ts
|
|
@@ -60252,7 +60636,13 @@ var requirementsOnlyText = (result3) => requirementsText(result3);
|
|
|
60252
60636
|
var badgeText = (result3) => {
|
|
60253
60637
|
if (result3.url)
|
|
60254
60638
|
return result3.url;
|
|
60255
|
-
|
|
60639
|
+
if (result3.status === "pending" || result3.status === "running") {
|
|
60640
|
+
return "Tu carnet se está generando.";
|
|
60641
|
+
}
|
|
60642
|
+
if (result3.status === "failed") {
|
|
60643
|
+
return "No se pudo generar tu carnet. Ejecuta `chofex badge regenerate` para intentarlo de nuevo.";
|
|
60644
|
+
}
|
|
60645
|
+
return "Todavía no tienes un carnet.";
|
|
60256
60646
|
};
|
|
60257
60647
|
|
|
60258
60648
|
// src/challenge-commands.ts
|
|
@@ -60364,7 +60754,7 @@ var challengeQuickstartText = (participationState, launchNotice) => {
|
|
|
60364
60754
|
};
|
|
60365
60755
|
var optionalString = (name, description) => exports_Flag.string(name).pipe(exports_Flag.optional, exports_Flag.withDescription(description));
|
|
60366
60756
|
var challengeFlag = exports_Flag.string("challenge").pipe(exports_Flag.withDefault(defaultChallengeSlug), exports_Flag.withDescription("Challenge slug (default: black-box)"));
|
|
60367
|
-
var sourceFlag = optionalString("source", "JavaScript
|
|
60757
|
+
var sourceFlag = optionalString("source", "JavaScript challenge solution file");
|
|
60368
60758
|
var inputFlag = optionalString("input", "JSON file, or - for stdin");
|
|
60369
60759
|
var formatFlag = exports_Flag.choice("format", ["table", "json", "csv"]).pipe(exports_Flag.withDefault("table"), exports_Flag.withDescription("Notebook format"));
|
|
60370
60760
|
var numberFromOption = (value3) => {
|
|
@@ -60381,6 +60771,30 @@ var booleanFromOption = (value3) => {
|
|
|
60381
60771
|
return false;
|
|
60382
60772
|
};
|
|
60383
60773
|
var challengeInitText = (result3) => {
|
|
60774
|
+
if (result3.challenge === "broken-agent") {
|
|
60775
|
+
if (result3.status === "exists") {
|
|
60776
|
+
return [
|
|
60777
|
+
`${result3.path} already exists. Left it unchanged.`,
|
|
60778
|
+
"",
|
|
60779
|
+
"Next: keep hardening your scheduler, then run the public tests",
|
|
60780
|
+
` cd ${result3.path} && npm test`,
|
|
60781
|
+
` chofex challenge test --challenge broken-agent --source ./${result3.path}/scheduler.js`
|
|
60782
|
+
].join(`
|
|
60783
|
+
`);
|
|
60784
|
+
}
|
|
60785
|
+
return [
|
|
60786
|
+
`Created ${result3.path}`,
|
|
60787
|
+
"The previous agent says the scheduler is done. Everything passes.",
|
|
60788
|
+
"Unfortunately, the agent was wrong.",
|
|
60789
|
+
"",
|
|
60790
|
+
"Start with the public contract and tests:",
|
|
60791
|
+
` cd ${result3.path} && npm test`,
|
|
60792
|
+
"",
|
|
60793
|
+
"Then repair scheduler.js and test it safely:",
|
|
60794
|
+
` chofex challenge test --challenge broken-agent --source ./${result3.path}/scheduler.js`
|
|
60795
|
+
].join(`
|
|
60796
|
+
`);
|
|
60797
|
+
}
|
|
60384
60798
|
if (result3.status === "exists") {
|
|
60385
60799
|
return [
|
|
60386
60800
|
`${result3.path} already exists. Left it unchanged.`,
|
|
@@ -60412,28 +60826,32 @@ var listCommand = exports_Command.make("list", {}, exports_Effect.fn("challengeL
|
|
|
60412
60826
|
description: "See which challenge is currently playable"
|
|
60413
60827
|
}
|
|
60414
60828
|
]));
|
|
60415
|
-
var initCommand = exports_Command.make("init", {}, exports_Effect.fn("challengeInitCommand")(function* () {
|
|
60829
|
+
var initCommand = exports_Command.make("init", { challenge: challengeFlag }, exports_Effect.fn("challengeInitCommand")(function* ({ challenge }) {
|
|
60416
60830
|
const options = yield* root;
|
|
60417
|
-
const participationState = participationStateFor(
|
|
60831
|
+
const participationState = participationStateFor(challenge);
|
|
60418
60832
|
if (participationState !== "open") {
|
|
60419
|
-
const message = launchNoticeFor(
|
|
60833
|
+
const message = launchNoticeFor(challenge) ?? "El challenge todavía no está disponible.";
|
|
60420
60834
|
let code = "CHALLENGE_NOT_OPEN";
|
|
60421
60835
|
if (participationState === "closed")
|
|
60422
60836
|
code = "CHALLENGE_CLOSED";
|
|
60423
60837
|
yield* execute(options.output, exports_Effect.fail(cliError(code, message)), challengeInitText);
|
|
60424
60838
|
return;
|
|
60425
60839
|
}
|
|
60426
|
-
const operation = createChallengeScaffold().pipe(exports_Effect.map((data) => ({
|
|
60840
|
+
const operation = createChallengeScaffold(challenge).pipe(exports_Effect.map((data) => ({
|
|
60427
60841
|
version: 1,
|
|
60428
60842
|
ok: true,
|
|
60429
60843
|
requestId: crypto.randomUUID(),
|
|
60430
60844
|
data
|
|
60431
60845
|
})));
|
|
60432
60846
|
yield* execute(options.output, operation, challengeInitText);
|
|
60433
|
-
})).pipe(exports_Command.withDescription("Create a
|
|
60847
|
+
})).pipe(exports_Command.withDescription("Create a challenge starter without overwriting existing work."), exports_Command.withExamples([
|
|
60434
60848
|
{
|
|
60435
60849
|
command: "chofex challenge init",
|
|
60436
60850
|
description: "Prepare a safe JavaScript solution file"
|
|
60851
|
+
},
|
|
60852
|
+
{
|
|
60853
|
+
command: "chofex challenge init --challenge broken-agent",
|
|
60854
|
+
description: "Prepare the Broken Agent starter repository"
|
|
60437
60855
|
}
|
|
60438
60856
|
]));
|
|
60439
60857
|
var showCommand = exports_Command.make("show", { challenge: challengeFlag }, exports_Effect.fn("challengeShowCommand")(function* ({ challenge }) {
|
|
@@ -60512,11 +60930,11 @@ var testCommand = exports_Command.make("test", { challenge: challengeFlag, sourc
|
|
|
60512
60930
|
const options = yield* root;
|
|
60513
60931
|
const token = exports_Option.getOrUndefined(options.token);
|
|
60514
60932
|
const operation = exports_Effect.gen(function* () {
|
|
60515
|
-
const solution = yield* javascriptSourceFromPath(exports_Option.getOrUndefined(source));
|
|
60933
|
+
const solution = yield* javascriptSourceFromPath(exports_Option.getOrUndefined(source), challenge);
|
|
60516
60934
|
return yield* testChallenge({ apiUrl: options.apiUrl, token }, challenge, solution);
|
|
60517
60935
|
});
|
|
60518
60936
|
yield* execute(options.output, operation, challengeTestText);
|
|
60519
|
-
})).pipe(exports_Command.withDescription("
|
|
60937
|
+
})).pipe(exports_Command.withDescription("Run the challenge's public tests. Safe to repeat; official evaluations are not consumed. Requires sign-in."), exports_Command.withExamples([
|
|
60520
60938
|
{
|
|
60521
60939
|
command: "chofex challenge test --source ./shipping.js",
|
|
60522
60940
|
description: "Test a JavaScript replacement against your notebook"
|
|
@@ -60526,11 +60944,11 @@ var evaluateCommand = exports_Command.make("evaluate", { challenge: challengeFla
|
|
|
60526
60944
|
const options = yield* root;
|
|
60527
60945
|
const token = exports_Option.getOrUndefined(options.token);
|
|
60528
60946
|
const operation = exports_Effect.gen(function* () {
|
|
60529
|
-
const solution = yield* javascriptSourceFromPath(exports_Option.getOrUndefined(source));
|
|
60947
|
+
const solution = yield* javascriptSourceFromPath(exports_Option.getOrUndefined(source), challenge);
|
|
60530
60948
|
return yield* evaluateChallenge({ apiUrl: options.apiUrl, token }, challenge, solution);
|
|
60531
60949
|
});
|
|
60532
60950
|
yield* execute(options.output, operation, challengeEvaluateText);
|
|
60533
|
-
})).pipe(exports_Command.withDescription("Score
|
|
60951
|
+
})).pipe(exports_Command.withDescription("Score a solution on hidden cases. This consumes one limited official evaluation. Requires sign-in."), exports_Command.withExamples([
|
|
60534
60952
|
{
|
|
60535
60953
|
command: "chofex challenge evaluate --source ./shipping.js",
|
|
60536
60954
|
description: "Spend one official evaluation when your solution is ready"
|
|
@@ -60975,6 +61393,34 @@ var picturePathInput = (suppliedPath) => {
|
|
|
60975
61393
|
}
|
|
60976
61394
|
return exports_Prompt.run(requiredText("Path to a JPEG, PNG, or WebP picture (5 MB maximum)", exports_Schema.String.pipe(exports_Schema.check(exports_Schema.isMinLength(1))))).pipe(exports_Effect.mapError(() => cliError("PROMPT_CANCELLED", "Interactive input was cancelled")));
|
|
60977
61395
|
};
|
|
61396
|
+
var badgeProfileInput = (path4, defaults2, pictures) => {
|
|
61397
|
+
const interactive = exports_Effect.gen(function* () {
|
|
61398
|
+
const publicFields = yield* exports_Prompt.run(exports_Prompt.all({
|
|
61399
|
+
fullName: requiredText("Nombre impreso en el carnet", exports_Schema.Trim.pipe(exports_Schema.check(exports_Schema.isMinLength(1), exports_Schema.isMaxLength(200))), defaults2.fullName),
|
|
61400
|
+
oneLiner: requiredText("Presentación de una línea", exports_Schema.Trim.pipe(exports_Schema.check(exports_Schema.isMinLength(1), exports_Schema.isMaxLength(30))), defaults2.oneLiner),
|
|
61401
|
+
linkUrl: requiredText("Destino del QR", exports_Schema.Trim.pipe(exports_Schema.check(exports_Schema.isMinLength(1), exports_Schema.isMaxLength(2048))), defaults2.linkUrl)
|
|
61402
|
+
}));
|
|
61403
|
+
const pictureChoices = [{ title: "Mantener mi foto actual", value: "keep" }];
|
|
61404
|
+
if (pictures.clerkPictureUrl) {
|
|
61405
|
+
pictureChoices.push({ title: "Usar mi foto de Clerk", value: "clerk" });
|
|
61406
|
+
}
|
|
61407
|
+
if (pictures.githubUrl) {
|
|
61408
|
+
pictureChoices.push({ title: "Usar mi foto de GitHub", value: "github" });
|
|
61409
|
+
}
|
|
61410
|
+
pictureChoices.push({
|
|
61411
|
+
title: "Subir otra foto",
|
|
61412
|
+
value: "upload"
|
|
61413
|
+
});
|
|
61414
|
+
const pictureChoice = yield* exports_Prompt.run(exports_Prompt.select({
|
|
61415
|
+
message: "Foto impresa en el carnet",
|
|
61416
|
+
choices: pictureChoices
|
|
61417
|
+
}));
|
|
61418
|
+
if (pictureChoice === "keep")
|
|
61419
|
+
return publicFields;
|
|
61420
|
+
return { ...publicFields, pictureSource: pictureChoice };
|
|
61421
|
+
});
|
|
61422
|
+
return inputOrInteractive(path4, interactive).pipe(exports_Effect.flatMap((input) => decode2(BadgeRegenerationInput, input, badgeRegenerationInputFieldNames)));
|
|
61423
|
+
};
|
|
60978
61424
|
|
|
60979
61425
|
// src/picture-upload.ts
|
|
60980
61426
|
import { readFile as readFile5, stat as stat3 } from "node:fs/promises";
|
|
@@ -62643,13 +63089,14 @@ var uploadPicture = exports_Effect.fn("uploadPicture")(function* (options, path4
|
|
|
62643
63089
|
import { spawn as spawn3 } from "node:child_process";
|
|
62644
63090
|
import { mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
|
|
62645
63091
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
62646
|
-
import { dirname as dirname2, join as join3 } from "node:path";
|
|
63092
|
+
import { dirname as dirname2, isAbsolute, join as join3, relative, sep } from "node:path";
|
|
62647
63093
|
var cliPackageName = "chofex-cli";
|
|
62648
63094
|
var upgradeVersion = "latest";
|
|
62649
|
-
var
|
|
63095
|
+
var npmRegistryUrl = `https://registry.npmjs.org/${cliPackageName}/latest`;
|
|
63096
|
+
var npmUpgradeArguments = (cacheDirectory, version) => [
|
|
62650
63097
|
"install",
|
|
62651
63098
|
"--global",
|
|
62652
|
-
`${cliPackageName}@${
|
|
63099
|
+
`${cliPackageName}@${version}`,
|
|
62653
63100
|
"--force",
|
|
62654
63101
|
"--prefer-online",
|
|
62655
63102
|
`--cache=${cacheDirectory}`
|
|
@@ -62657,22 +63104,32 @@ var npmUpgradeArguments = (cacheDirectory) => [
|
|
|
62657
63104
|
var runProcess = (executable, arguments_, input) => new Promise((resolve4, reject) => {
|
|
62658
63105
|
const stdin = input === undefined ? "ignore" : "pipe";
|
|
62659
63106
|
const child = spawn3(executable, arguments_, {
|
|
62660
|
-
stdio: [stdin, "
|
|
63107
|
+
stdio: [stdin, "pipe", "pipe"]
|
|
62661
63108
|
});
|
|
63109
|
+
let stdout = "";
|
|
62662
63110
|
let stderr = "";
|
|
63111
|
+
const stdoutStream = child.stdout;
|
|
62663
63112
|
const stderrStream = child.stderr;
|
|
62664
|
-
if (stderrStream === null) {
|
|
63113
|
+
if (stdoutStream === null || stderrStream === null) {
|
|
62665
63114
|
child.kill();
|
|
62666
|
-
reject(new Error(`Could not capture
|
|
63115
|
+
reject(new Error(`Could not capture output from ${executable}`));
|
|
62667
63116
|
return;
|
|
62668
63117
|
}
|
|
63118
|
+
stdoutStream.setEncoding("utf8");
|
|
63119
|
+
stdoutStream.on("data", (chunk) => {
|
|
63120
|
+
stdout += chunk;
|
|
63121
|
+
});
|
|
62669
63122
|
stderrStream.setEncoding("utf8");
|
|
62670
63123
|
stderrStream.on("data", (chunk) => {
|
|
62671
63124
|
stderr += chunk;
|
|
62672
63125
|
});
|
|
62673
63126
|
child.on("error", reject);
|
|
62674
63127
|
child.on("close", (exitCode) => {
|
|
62675
|
-
resolve4({
|
|
63128
|
+
resolve4({
|
|
63129
|
+
exitCode: exitCode ?? 1,
|
|
63130
|
+
stdout: stdout.trim(),
|
|
63131
|
+
stderr: stderr.trim()
|
|
63132
|
+
});
|
|
62676
63133
|
});
|
|
62677
63134
|
if (input !== undefined) {
|
|
62678
63135
|
const stdinStream = child.stdin;
|
|
@@ -62689,7 +63146,7 @@ var runNpm = (arguments_) => {
|
|
|
62689
63146
|
return runProcess(executable, arguments_);
|
|
62690
63147
|
};
|
|
62691
63148
|
var installerUrl = "https://hacktheandes.com/install";
|
|
62692
|
-
var runInstaller = async (installDirectory) => {
|
|
63149
|
+
var runInstaller = async (installDirectory, version) => {
|
|
62693
63150
|
const response = await fetch(installerUrl);
|
|
62694
63151
|
if (!response.ok) {
|
|
62695
63152
|
throw new Error(`installer download returned HTTP ${response.status}`);
|
|
@@ -62698,6 +63155,8 @@ var runInstaller = async (installDirectory) => {
|
|
|
62698
63155
|
const arguments_ = [
|
|
62699
63156
|
"-s",
|
|
62700
63157
|
"--",
|
|
63158
|
+
"--version",
|
|
63159
|
+
version,
|
|
62701
63160
|
"--install-dir",
|
|
62702
63161
|
installDirectory,
|
|
62703
63162
|
"--no-modify-path"
|
|
@@ -62717,22 +63176,160 @@ var assertSuccessful = (result3, program) => {
|
|
|
62717
63176
|
throw new Error(`${program} exited with code ${result3.exitCode}${detail}`);
|
|
62718
63177
|
};
|
|
62719
63178
|
var upgradeCli = async (options = {}) => {
|
|
63179
|
+
const version = options.version ?? upgradeVersion;
|
|
62720
63180
|
const standalone = options.standalone ?? isStandaloneExecutable();
|
|
62721
63181
|
if (standalone) {
|
|
62722
63182
|
const runner2 = options.installerRunner ?? runInstaller;
|
|
62723
|
-
const result3 = await runner2(dirname2(process.execPath));
|
|
63183
|
+
const result3 = await runner2(dirname2(process.execPath), version);
|
|
62724
63184
|
assertSuccessful(result3, "installer");
|
|
62725
63185
|
return;
|
|
62726
63186
|
}
|
|
62727
63187
|
const runner = options.npmRunner ?? runNpm;
|
|
62728
63188
|
const cacheDirectory = await mkdtemp2(join3(tmpdir2(), "chofex-npm-cache-"));
|
|
62729
63189
|
try {
|
|
62730
|
-
const result3 = await runner(npmUpgradeArguments(cacheDirectory));
|
|
63190
|
+
const result3 = await runner(npmUpgradeArguments(cacheDirectory, version));
|
|
62731
63191
|
assertSuccessful(result3, "npm");
|
|
62732
63192
|
} finally {
|
|
62733
63193
|
await rm2(cacheDirectory, { recursive: true, force: true });
|
|
62734
63194
|
}
|
|
62735
63195
|
};
|
|
63196
|
+
var parseVersion = (version) => {
|
|
63197
|
+
const match9 = version.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/);
|
|
63198
|
+
if (match9 === null)
|
|
63199
|
+
throw new Error(`Invalid CLI version: ${version}`);
|
|
63200
|
+
return {
|
|
63201
|
+
core: [Number(match9[1]), Number(match9[2]), Number(match9[3])],
|
|
63202
|
+
prerelease: match9[4]?.split(".") ?? []
|
|
63203
|
+
};
|
|
63204
|
+
};
|
|
63205
|
+
var comparePrereleaseIdentifier = (left, right) => {
|
|
63206
|
+
const leftNumber = /^\d+$/.test(left) ? Number(left) : undefined;
|
|
63207
|
+
const rightNumber = /^\d+$/.test(right) ? Number(right) : undefined;
|
|
63208
|
+
if (leftNumber !== undefined && rightNumber !== undefined) {
|
|
63209
|
+
return leftNumber - rightNumber;
|
|
63210
|
+
}
|
|
63211
|
+
if (leftNumber !== undefined)
|
|
63212
|
+
return -1;
|
|
63213
|
+
if (rightNumber !== undefined)
|
|
63214
|
+
return 1;
|
|
63215
|
+
return left.localeCompare(right);
|
|
63216
|
+
};
|
|
63217
|
+
var compareVersions = (left, right) => {
|
|
63218
|
+
const parsedLeft = parseVersion(left);
|
|
63219
|
+
const parsedRight = parseVersion(right);
|
|
63220
|
+
const [leftMajor, leftMinor, leftPatch] = parsedLeft.core;
|
|
63221
|
+
const [rightMajor, rightMinor, rightPatch] = parsedRight.core;
|
|
63222
|
+
for (const difference3 of [
|
|
63223
|
+
leftMajor - rightMajor,
|
|
63224
|
+
leftMinor - rightMinor,
|
|
63225
|
+
leftPatch - rightPatch
|
|
63226
|
+
]) {
|
|
63227
|
+
if (difference3 !== 0)
|
|
63228
|
+
return difference3;
|
|
63229
|
+
}
|
|
63230
|
+
if (parsedLeft.prerelease.length === 0) {
|
|
63231
|
+
return parsedRight.prerelease.length === 0 ? 0 : 1;
|
|
63232
|
+
}
|
|
63233
|
+
if (parsedRight.prerelease.length === 0)
|
|
63234
|
+
return -1;
|
|
63235
|
+
const identifierCount = Math.max(parsedLeft.prerelease.length, parsedRight.prerelease.length);
|
|
63236
|
+
for (let index2 = 0;index2 < identifierCount; index2 += 1) {
|
|
63237
|
+
const leftIdentifier = parsedLeft.prerelease[index2];
|
|
63238
|
+
const rightIdentifier = parsedRight.prerelease[index2];
|
|
63239
|
+
if (leftIdentifier === undefined)
|
|
63240
|
+
return -1;
|
|
63241
|
+
if (rightIdentifier === undefined)
|
|
63242
|
+
return 1;
|
|
63243
|
+
const difference3 = comparePrereleaseIdentifier(leftIdentifier, rightIdentifier);
|
|
63244
|
+
if (difference3 !== 0)
|
|
63245
|
+
return difference3;
|
|
63246
|
+
}
|
|
63247
|
+
return 0;
|
|
63248
|
+
};
|
|
63249
|
+
var fetchLatestVersion = async () => {
|
|
63250
|
+
const response = await fetch(npmRegistryUrl, {
|
|
63251
|
+
headers: { accept: "application/json" },
|
|
63252
|
+
signal: AbortSignal.timeout(5000)
|
|
63253
|
+
});
|
|
63254
|
+
if (!response.ok) {
|
|
63255
|
+
throw new Error(`npm registry returned HTTP ${response.status}`);
|
|
63256
|
+
}
|
|
63257
|
+
const metadata = await response.json();
|
|
63258
|
+
if (typeof metadata !== "object" || metadata === null || !("version" in metadata) || typeof metadata.version !== "string") {
|
|
63259
|
+
throw new Error("npm registry returned an invalid package version");
|
|
63260
|
+
}
|
|
63261
|
+
parseVersion(metadata.version);
|
|
63262
|
+
return metadata.version;
|
|
63263
|
+
};
|
|
63264
|
+
var autoUpdateCli = async (currentVersion, options = {}) => {
|
|
63265
|
+
const latestVersion = await (options.fetchLatestVersion ?? fetchLatestVersion)();
|
|
63266
|
+
if (compareVersions(latestVersion, currentVersion) <= 0) {
|
|
63267
|
+
return { status: "current", version: currentVersion };
|
|
63268
|
+
}
|
|
63269
|
+
const upgrade = options.upgrade ?? ((version) => upgradeCli({ version }));
|
|
63270
|
+
await upgrade(latestVersion);
|
|
63271
|
+
return {
|
|
63272
|
+
status: "updated",
|
|
63273
|
+
previousVersion: currentVersion,
|
|
63274
|
+
version: latestVersion
|
|
63275
|
+
};
|
|
63276
|
+
};
|
|
63277
|
+
var npmGlobalNodeModulesPath = async (runner = runNpm) => {
|
|
63278
|
+
const result3 = await runner(["root", "--global"]);
|
|
63279
|
+
assertSuccessful(result3, "npm");
|
|
63280
|
+
if (!result3.stdout)
|
|
63281
|
+
throw new Error("npm did not report its global root");
|
|
63282
|
+
return result3.stdout;
|
|
63283
|
+
};
|
|
63284
|
+
var pathIsInside = (parent, child) => {
|
|
63285
|
+
const pathFromParent = relative(parent, child);
|
|
63286
|
+
return pathFromParent !== "" && pathFromParent !== ".." && !pathFromParent.startsWith(`..${sep}`) && !isAbsolute(pathFromParent);
|
|
63287
|
+
};
|
|
63288
|
+
var rootFlagsWithValues = new Set(Object.values(rootValueFlagNames).map((name) => `--${name}`));
|
|
63289
|
+
var requestedCommand = (arguments_) => {
|
|
63290
|
+
for (let index2 = 0;index2 < arguments_.length; index2 += 1) {
|
|
63291
|
+
const argument = arguments_[index2];
|
|
63292
|
+
if (argument === undefined)
|
|
63293
|
+
continue;
|
|
63294
|
+
if (rootFlagsWithValues.has(argument)) {
|
|
63295
|
+
index2 += 1;
|
|
63296
|
+
continue;
|
|
63297
|
+
}
|
|
63298
|
+
if (argument.startsWith("-"))
|
|
63299
|
+
continue;
|
|
63300
|
+
return argument;
|
|
63301
|
+
}
|
|
63302
|
+
return;
|
|
63303
|
+
};
|
|
63304
|
+
var shouldAutoUpdateCli = async ({
|
|
63305
|
+
arguments: arguments_,
|
|
63306
|
+
entryPath,
|
|
63307
|
+
environmentValue,
|
|
63308
|
+
globalNodeModulesPath,
|
|
63309
|
+
npmRunner,
|
|
63310
|
+
standalone
|
|
63311
|
+
}) => {
|
|
63312
|
+
if (environmentValue === "0" || environmentValue === "false")
|
|
63313
|
+
return false;
|
|
63314
|
+
const command = requestedCommand(arguments_);
|
|
63315
|
+
if (command === "update" || command === "upgrade") {
|
|
63316
|
+
return false;
|
|
63317
|
+
}
|
|
63318
|
+
if (standalone)
|
|
63319
|
+
return true;
|
|
63320
|
+
if (!entryPath.split(/[\\/]/).includes("node_modules"))
|
|
63321
|
+
return false;
|
|
63322
|
+
const npmRoot = globalNodeModulesPath ?? await npmGlobalNodeModulesPath(npmRunner);
|
|
63323
|
+
return pathIsInside(join3(npmRoot, cliPackageName), entryPath);
|
|
63324
|
+
};
|
|
63325
|
+
var runUpdatedCli = () => new Promise((resolve4, reject) => {
|
|
63326
|
+
const child = spawn3(process.execPath, process.argv.slice(1), {
|
|
63327
|
+
env: { ...process.env, CHOFEX_AUTO_UPDATE: "0" },
|
|
63328
|
+
stdio: "inherit"
|
|
63329
|
+
});
|
|
63330
|
+
child.on("error", reject);
|
|
63331
|
+
child.on("close", (exitCode) => resolve4(exitCode ?? 1));
|
|
63332
|
+
});
|
|
62736
63333
|
|
|
62737
63334
|
// src/commands.ts
|
|
62738
63335
|
var inputFlag2 = exports_Flag.string("input").pipe(exports_Flag.optional, exports_Flag.withDescription("Read JSON from a file, or use - for stdin"));
|
|
@@ -62819,12 +63416,50 @@ var requirementsCommand = exports_Command.make("requirements", {}, exports_Effec
|
|
|
62819
63416
|
});
|
|
62820
63417
|
yield* execute(options.output, operation, requirementsOnlyText, registrationLookupErrorText);
|
|
62821
63418
|
})).pipe(exports_Command.withDescription("Show information you still need to provide"));
|
|
63419
|
+
var badgeRegenerateCommand = exports_Command.make("regenerate", {
|
|
63420
|
+
input: inputFlag2,
|
|
63421
|
+
picture: exports_Flag.string("picture").pipe(exports_Flag.optional, exports_Flag.withDescription("Ruta a una foto JPEG, PNG o WebP (máximo 5 MB)"))
|
|
63422
|
+
}, exports_Effect.fn("badgeRegenerateCommand")(function* ({ input, picture }) {
|
|
63423
|
+
const options = yield* root;
|
|
63424
|
+
const operation = exports_Effect.gen(function* () {
|
|
63425
|
+
const inputPath = exports_Option.getOrUndefined(input);
|
|
63426
|
+
if (options.output === "json" && inputPath === undefined) {
|
|
63427
|
+
return yield* exports_Effect.fail(cliError("INPUT_REQUIRED", "El modo JSON requiere --input <archivo> o --input -"));
|
|
63428
|
+
}
|
|
63429
|
+
const token = exports_Option.getOrUndefined(options.token);
|
|
63430
|
+
const client = { apiUrl: options.apiUrl, token };
|
|
63431
|
+
const badge = yield* getBadge(client);
|
|
63432
|
+
if (!badge.data.profile) {
|
|
63433
|
+
return yield* exports_Effect.fail(cliError("INVALID_APPLICATION_STATE", "Confirma tu asistencia antes de regenerar tu carnet"));
|
|
63434
|
+
}
|
|
63435
|
+
const [current, currentUser] = yield* exports_Effect.all([
|
|
63436
|
+
getRegistration(client),
|
|
63437
|
+
getCurrentUser(client)
|
|
63438
|
+
]);
|
|
63439
|
+
const body = yield* badgeProfileInput(inputPath, badge.data.profile, {
|
|
63440
|
+
clerkPictureUrl: currentUser.data.clerkPictureUrl,
|
|
63441
|
+
githubUrl: current.data.registration.githubUrl
|
|
63442
|
+
});
|
|
63443
|
+
const picturePath = exports_Option.getOrUndefined(picture);
|
|
63444
|
+
if (body.pictureSource === "upload") {
|
|
63445
|
+
if (options.output === "json" && picturePath === undefined) {
|
|
63446
|
+
return yield* exports_Effect.fail(cliError("PICTURE_PATH_REQUIRED", "Usa --picture <ruta> cuando pictureSource es upload"));
|
|
63447
|
+
}
|
|
63448
|
+
const path4 = yield* picturePathInput(picturePath);
|
|
63449
|
+
yield* uploadPicture(client, path4);
|
|
63450
|
+
} else if (picturePath) {
|
|
63451
|
+
return yield* exports_Effect.fail(cliError("UNEXPECTED_PICTURE_PATH", "--picture solo se puede usar cuando pictureSource es upload"));
|
|
63452
|
+
}
|
|
63453
|
+
return yield* regenerateBadge(client, body);
|
|
63454
|
+
});
|
|
63455
|
+
yield* execute(options.output, operation, badgeText);
|
|
63456
|
+
})).pipe(exports_Command.withDescription("Actualiza la foto, el nombre, la presentación y el enlace QR del carnet"));
|
|
62822
63457
|
var badgeCommand = exports_Command.make("badge", {}, exports_Effect.fn("badgeCommand")(function* () {
|
|
62823
63458
|
const options = yield* root;
|
|
62824
63459
|
const token = exports_Option.getOrUndefined(options.token);
|
|
62825
63460
|
const operation = getBadge({ apiUrl: options.apiUrl, token });
|
|
62826
63461
|
yield* execute(options.output, operation, badgeText);
|
|
62827
|
-
})).pipe(exports_Command.withDescription("
|
|
63462
|
+
})).pipe(exports_Command.withDescription("Muestra o regenera tu carnet de participante"), exports_Command.withSubcommands([badgeRegenerateCommand]));
|
|
62828
63463
|
var confirmCommand = exports_Command.make("confirm", {
|
|
62829
63464
|
input: inputFlag2,
|
|
62830
63465
|
picture: exports_Flag.string("picture").pipe(exports_Flag.optional, exports_Flag.withDescription("Path to a JPEG, PNG, or WebP picture (5 MB max)"))
|
|
@@ -63259,4 +63894,37 @@ var programForArguments = () => {
|
|
|
63259
63894
|
}
|
|
63260
63895
|
return commandProgram;
|
|
63261
63896
|
};
|
|
63262
|
-
|
|
63897
|
+
var runAutomaticUpdate = async () => {
|
|
63898
|
+
try {
|
|
63899
|
+
const standalone = isStandaloneExecutable();
|
|
63900
|
+
const enabled = await shouldAutoUpdateCli({
|
|
63901
|
+
arguments: arguments_,
|
|
63902
|
+
entryPath: fileURLToPath2(import.meta.url),
|
|
63903
|
+
environmentValue: process.env.CHOFEX_AUTO_UPDATE,
|
|
63904
|
+
standalone
|
|
63905
|
+
});
|
|
63906
|
+
if (!enabled)
|
|
63907
|
+
return "continue";
|
|
63908
|
+
const result3 = await autoUpdateCli(cliVersion);
|
|
63909
|
+
if (result3.status === "current")
|
|
63910
|
+
return "continue";
|
|
63911
|
+
process.stderr.write(`${cliPackageName} se actualizó de ${result3.previousVersion} a ${result3.version}.
|
|
63912
|
+
`);
|
|
63913
|
+
if (standalone && process.platform === "win32") {
|
|
63914
|
+
process.stderr.write(`La actualización se aplicará cuando termine este comando.
|
|
63915
|
+
`);
|
|
63916
|
+
return "continue";
|
|
63917
|
+
}
|
|
63918
|
+
process.exitCode = await runUpdatedCli();
|
|
63919
|
+
return "command-completed";
|
|
63920
|
+
} catch {
|
|
63921
|
+
process.stderr.write(`No se pudo comprobar o instalar una actualización de ${cliPackageName}; se continuará con ${cliVersion}.
|
|
63922
|
+
`);
|
|
63923
|
+
return "continue";
|
|
63924
|
+
}
|
|
63925
|
+
};
|
|
63926
|
+
exports_Effect.promise(runAutomaticUpdate).pipe(exports_Effect.flatMap((outcome) => {
|
|
63927
|
+
if (outcome === "command-completed")
|
|
63928
|
+
return exports_Effect.void;
|
|
63929
|
+
return programForArguments();
|
|
63930
|
+
}), exports_Effect.provide(exports_NodeServices.layer), (program) => exports_NodeRuntime.runMain(program, { disableErrorReporting: true }));
|