chofex-cli 0.1.190 → 0.1.191

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +6 -3
  2. package/dist/index.js +102 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -51,9 +51,12 @@ Acceptance creates a default badge from the Clerk profile visible to reviewers.
51
51
  while separately collecting the legal full name and venue details required for attendance. After confirmation,
52
52
  `chofex badge regenerate` can also update those public fields and the QR
53
53
  destination without changing the submitted application.
54
- The technical challenges do not block submission, but every challenge winner must submit
55
- an application before being accepted. Top results receive a direct pass; other
56
- scores give organizers another review metric.
54
+ The technical challenges do not block application submission, but they are
55
+ mandatory for admission. An application does not reserve a seat; organizers
56
+ select the strongest engineers from challenge rankings. Broken Agent requires a
57
+ participant-only browser handoff with passkey user verification before each
58
+ official evaluation. Every challenge slug resolves to the current server
59
+ version; legacy attempts do not count toward admission.
57
60
 
58
61
  The public ranking is read-only at `https://hacktheandes.com/challenges`.
59
62
 
package/dist/index.js CHANGED
@@ -58554,6 +58554,7 @@ var runWith2 = (command, config) => {
58554
58554
  // ../../packages/challenges-contract/src/index.ts
58555
58555
  var blackBoxChallengeSlug = "black-box";
58556
58556
  var brokenAgentChallengeSlug = "broken-agent";
58557
+ var challengeAdmissionNotice = "Los challenges técnicos son obligatorios para competir por un cupo. Enviar la postulación solo crea tu candidatura: no reserva una plaza. Siempre compites en la versión vigente; los intentos legacy no cuentan. Los mejores resultados de los rankings serán seleccionados para el evento.";
58557
58558
  var challengeCatalog = [
58558
58559
  {
58559
58560
  slug: blackBoxChallengeSlug,
@@ -58836,6 +58837,7 @@ var ChallengeCatalogItemSchema = exports_Schema.Struct({
58836
58837
  playable: exports_Schema.Boolean,
58837
58838
  open: exports_Schema.Boolean,
58838
58839
  closed: exports_Schema.optional(exports_Schema.Boolean),
58840
+ challengeVersion: exports_Schema.optional(exports_Schema.String),
58839
58841
  rankingPath: exports_Schema.String
58840
58842
  });
58841
58843
  var ChallengeEvaluationSummarySchema = exports_Schema.Struct({
@@ -58853,6 +58855,11 @@ var ChallengeEvaluationSummarySchema = exports_Schema.Struct({
58853
58855
  breakdown: exports_Schema.optional(ChallengeScoreSchema.fields.breakdown)
58854
58856
  });
58855
58857
  var ChallengeAttemptViewSchema = exports_Schema.Struct({
58858
+ admission: exports_Schema.optional(exports_Schema.Struct({
58859
+ challengesMandatory: exports_Schema.Literal(true),
58860
+ selectionBasis: exports_Schema.Literal("challenge_rankings"),
58861
+ notice: exports_Schema.String
58862
+ })),
58856
58863
  challenge: ChallengeCatalogItemSchema,
58857
58864
  progress: ParticipantChallengeProgressSchema,
58858
58865
  observations: exports_Schema.Array(ChallengeObservationSchema),
@@ -58918,6 +58925,11 @@ var ChallengeRankingSchema = exports_Schema.Struct({
58918
58925
  competitorCount: exports_Schema.Number
58919
58926
  });
58920
58927
  var ChallengeCatalogSchema = exports_Schema.Struct({
58928
+ admission: exports_Schema.optional(exports_Schema.Struct({
58929
+ challengesMandatory: exports_Schema.Literal(true),
58930
+ selectionBasis: exports_Schema.Literal("challenge_rankings"),
58931
+ notice: exports_Schema.String
58932
+ })),
58921
58933
  challenges: exports_Schema.Array(ChallengeCatalogItemSchema)
58922
58934
  });
58923
58935
 
@@ -59267,7 +59279,12 @@ var PictureUploadCompletionSchema = exports_Schema.Struct({
59267
59279
  });
59268
59280
  var RegistrationResultSchema = exports_Schema.Struct({
59269
59281
  registration: RegistrationViewSchema,
59270
- requirements: RegistrationRequirementsSchema
59282
+ requirements: RegistrationRequirementsSchema,
59283
+ admission: exports_Schema.optional(exports_Schema.Struct({
59284
+ challengesMandatory: exports_Schema.Literal(true),
59285
+ selectionBasis: exports_Schema.Literal("challenge_rankings"),
59286
+ notice: exports_Schema.String
59287
+ }))
59271
59288
  });
59272
59289
  var CreatedRegistrationSchema = RegistrationResultSchema;
59273
59290
  var ApiSuccessSchema = (data) => exports_Schema.Struct({
@@ -59942,7 +59959,12 @@ var challengeParticipationNotice = (title, opensAt, closesAt, now3 = new Date) =
59942
59959
  return challengeLaunchNotice(title, opensAt, now3);
59943
59960
  };
59944
59961
  var challengeListText = (catalog) => {
59945
- const lines2 = [`${eventName} challenges`, ""];
59962
+ const lines2 = [
59963
+ `${eventName} challenges`,
59964
+ "",
59965
+ catalog.admission?.notice ?? challengeAdmissionNotice,
59966
+ ""
59967
+ ];
59946
59968
  for (const challenge of catalog.challenges) {
59947
59969
  let state = `abre ${formatChallengeOpeningInPeru(challenge.opensAt)}`;
59948
59970
  if (challenge.closed) {
@@ -59955,6 +59977,9 @@ var challengeListText = (catalog) => {
59955
59977
  const playable = challenge.playable ? "" : " (próximamente)";
59956
59978
  lines2.push(`${challenge.code} ${challenge.theme} — ${challenge.title}${playable}`);
59957
59979
  lines2.push(` ${challenge.coreSkill} · ${challenge.formatLabel} · ${state}`);
59980
+ if (challenge.challengeVersion) {
59981
+ lines2.push(` Versión vigente: ${challenge.challengeVersion}`);
59982
+ }
59958
59983
  lines2.push(` Ranking: ${challenge.rankingPath}`);
59959
59984
  lines2.push("");
59960
59985
  }
@@ -59979,6 +60004,10 @@ var challengeShowText = (attempt) => {
59979
60004
  `${challenge.title.toUpperCase()} — CASO #${challenge.code}`,
59980
60005
  challenge.summary,
59981
60006
  "",
60007
+ attempt.admission?.notice ?? challengeAdmissionNotice,
60008
+ "",
60009
+ `VERSIÓN VIGENTE: ${challenge.challengeVersion ?? "administrada por el servidor"}`,
60010
+ "",
59982
60011
  `ESTADO DEL CASO: ${caseStatus2}`,
59983
60012
  "",
59984
60013
  "Los tests públicos están verdes. Tu trabajo es hacer que el scheduler sea confiable bajo condiciones de producción.",
@@ -60011,6 +60040,10 @@ var challengeShowText = (attempt) => {
60011
60040
  `${challenge.title.toUpperCase()} — CASE #${challenge.code}`,
60012
60041
  challenge.summary,
60013
60042
  "",
60043
+ attempt.admission?.notice ?? challengeAdmissionNotice,
60044
+ "",
60045
+ `CURRENT VERSION: ${challenge.challengeVersion ?? "server-managed"}`,
60046
+ "",
60014
60047
  `CASE STATUS: ${caseStatus}`,
60015
60048
  "",
60016
60049
  "Your job is to replace the machine, not merely guess its next answer.",
@@ -60500,6 +60533,10 @@ contra escenarios ocultos. Las herramientas de AI están permitidas, pero este e
60500
60533
  un challenge de colaboración: el agente implementa y el participante toma las
60501
60534
  decisiones de ingeniería.
60502
60535
 
60536
+ Los challenges técnicos son obligatorios para competir por un cupo. Enviar la
60537
+ postulación solo crea tu candidatura: no reserva una plaza. Los mejores
60538
+ resultados de los rankings serán seleccionados para el evento.
60539
+
60503
60540
  ## Protocolo humano–agente
60504
60541
 
60505
60542
  No le pidas al agente que resuelva todo en silencio. Antes de modificar el
@@ -60541,6 +60578,13 @@ explicar, debatir y guardar tus respuestas, pero no puede elegir el foco, invent
60541
60578
  tu razonamiento ni tomar la decisión de release por ti. Si cambias
60542
60579
  \`scheduler.js\`, vuelve a revisar la evidencia antes de reemplazar el review.
60543
60580
 
60581
+ La primera ejecución de \`challenge evaluate\` crea un enlace corto de
60582
+ aprobación y **no consume** una evaluación. Abre ese enlace personalmente,
60583
+ revisa el review vinculado al SHA-256 exacto y confirma con Face ID, Touch ID,
60584
+ Windows Hello, PIN del dispositivo o una llave de seguridad. Después repite el
60585
+ mismo comando para ejecutar la evaluación oficial. Cada evaluación requiere una
60586
+ aprobación nueva; la sesión OAuth del CLI no puede aprobarla.
60587
+
60544
60588
  ## Contrato normativo
60545
60589
 
60546
60590
  \`createScheduler({ store, clock, execute, workerId })\` devuelve:
@@ -60821,7 +60865,7 @@ var root = exports_Command.make("chofex").pipe(exports_Command.withSharedFlags({
60821
60865
  apiUrl: exports_Flag.string(rootValueFlagNames.apiUrl).pipe(exports_Flag.withDefault(config.apiUrl), exports_Flag.withDescription("Chofex API base URL")),
60822
60866
  output: exports_Flag.choice(rootValueFlagNames.output, ["human", "json"]).pipe(exports_Flag.withDefault("human"), exports_Flag.withDescription("Output format")),
60823
60867
  token: exports_Flag.string(rootValueFlagNames.token).pipe(exports_Flag.optional, exports_Flag.withDescription("Clerk OAuth token (prefer CHOFEX_TOKEN to avoid shell history)"))
60824
- }), exports_Command.withDescription(`Register for and manage your ${eventName} application`));
60868
+ }), exports_Command.withDescription(`Apply to ${eventName} and compete for a seat through the mandatory technical challenges`));
60825
60869
 
60826
60870
  // src/output.ts
60827
60871
  var printJson = (value3) => exports_Effect.sync(() => {
@@ -60900,8 +60944,14 @@ var requirementsText = (result3) => {
60900
60944
  if (requirements.stage === "draft") {
60901
60945
  return `Application draft in progress.${registrationPartsText(result3)}`;
60902
60946
  }
60903
- if (requirements.stage === "review")
60904
- return "No action needed while your application is reviewed.";
60947
+ if (requirements.stage === "review") {
60948
+ return [
60949
+ "Application received. A seat has not been assigned.",
60950
+ result3.admission?.notice ?? challengeAdmissionNotice,
60951
+ "Next command: chofex challenge"
60952
+ ].join(`
60953
+ `);
60954
+ }
60905
60955
  let feedback = "";
60906
60956
  const rejectionReason = requirements.rejectionReason ?? registration.rejectionReason;
60907
60957
  if (rejectionReason) {
@@ -60960,6 +61010,8 @@ var challengeQuickstart = {
60960
61010
  ],
60961
61011
  mission: "Audita scheduler.js, conserva createScheduler(dependencies) y haz que el sistema cumpla el contrato de producción.",
60962
61012
  rules: [
61013
+ "Los challenges son obligatorios: enviar la postulación no reserva un cupo.",
61014
+ "Los mejores resultados de los rankings serán seleccionados para el evento.",
60963
61015
  "Tienes 5 evaluaciones oficiales contra variantes ocultas y determinísticas por participante.",
60964
61016
  "Los tests locales y públicos son ilimitados.",
60965
61017
  "Gana el puntaje total; los empates usan menos evaluaciones, costo determinístico y hora del mejor envío.",
@@ -61016,12 +61068,24 @@ var challengeQuickstart = {
61016
61068
  },
61017
61069
  {
61018
61070
  step: 9,
61019
- action: "Solicita un veredicto oculto",
61071
+ action: "Crea el handoff de evaluación",
61020
61072
  command: "chofex challenge evaluate --challenge broken-agent --source ./scheduler.js --review ./review.json",
61021
- note: "Úsalo solo cuando enviarías la implementación a producción."
61073
+ note: "Devuelve un enlace de aprobación sin consumir una evaluación oficial."
61022
61074
  },
61023
61075
  {
61024
61076
  step: 10,
61077
+ action: "El participante aprueba en el navegador",
61078
+ command: "Abre approvalUrl personalmente",
61079
+ note: "Revisa el razonamiento y confirma con Face ID, Touch ID, Windows Hello, PIN o llave de seguridad. El agente no puede completar este paso."
61080
+ },
61081
+ {
61082
+ step: 11,
61083
+ action: "Solicita el veredicto oculto",
61084
+ command: "chofex challenge evaluate --challenge broken-agent --source ./scheduler.js --review ./review.json",
61085
+ note: "Repite el mismo comando antes de que venza la aprobación; recién entonces consume una evaluación."
61086
+ },
61087
+ {
61088
+ step: 12,
61025
61089
  action: "Consulta el ranking",
61026
61090
  command: "chofex challenge ranking --challenge broken-agent",
61027
61091
  note: "Se revela el 1 de octubre a las 15:00, hora de Perú."
@@ -61074,6 +61138,34 @@ var optionalString = (name, description) => exports_Flag.string(name).pipe(expor
61074
61138
  var challengeFlag = exports_Flag.string("challenge").pipe(exports_Flag.withDefault(defaultChallengeSlug), exports_Flag.withDescription("Challenge slug (default: broken-agent)"));
61075
61139
  var sourceFlag = optionalString("source", "JavaScript challenge solution file");
61076
61140
  var reviewFlag = optionalString("review", "Participant-authored Broken Agent engineering review JSON");
61141
+ var evaluationErrorText = (error2) => {
61142
+ if (error2.code !== "HUMAN_APPROVAL_REQUIRED")
61143
+ return;
61144
+ if (!error2.details || typeof error2.details !== "object")
61145
+ return;
61146
+ const details = error2.details;
61147
+ if (typeof details.approvalUrl !== "string")
61148
+ return;
61149
+ let retryCommand = "chofex challenge evaluate --challenge broken-agent --source ./scheduler.js --review ./review.json";
61150
+ if (typeof details.retryCommand === "string") {
61151
+ retryCommand = details.retryCommand;
61152
+ }
61153
+ const lines2 = [
61154
+ "INTERVENCIÓN DEL PARTICIPANTE REQUERIDA",
61155
+ "La evaluación todavía no consumió un intento.",
61156
+ "",
61157
+ "El participante debe abrir personalmente este enlace, revisar sus respuestas y aprobar con Face ID, Touch ID, Windows Hello, PIN o llave de seguridad:",
61158
+ ` ${details.approvalUrl}`,
61159
+ "",
61160
+ "Después de aprobar, repite:",
61161
+ ` ${retryCommand}`
61162
+ ];
61163
+ if (typeof details.expiresAt === "string") {
61164
+ lines2.push("", `La aprobación vence: ${details.expiresAt}`);
61165
+ }
61166
+ return lines2.join(`
61167
+ `);
61168
+ };
61077
61169
  var inputFlag = optionalString("input", "JSON file, or - for stdin");
61078
61170
  var formatFlag = exports_Flag.choice("format", ["table", "json", "csv"]).pipe(exports_Flag.withDefault("table"), exports_Flag.withDescription("Notebook format"));
61079
61171
  var numberFromOption = (value3) => {
@@ -61270,8 +61362,8 @@ var evaluateCommand = exports_Command.make("evaluate", { challenge: challengeFla
61270
61362
  const solution = yield* challengeEvaluationInput(exports_Option.getOrUndefined(source), exports_Option.getOrUndefined(review), challenge);
61271
61363
  return yield* evaluateChallenge({ apiUrl: options.apiUrl, token }, challenge, solution);
61272
61364
  });
61273
- yield* execute(options.output, operation, challengeEvaluateText);
61274
- })).pipe(exports_Command.withDescription("Score a solution on hidden cases. This consumes one limited official evaluation. Requires sign-in."), exports_Command.withExamples([
61365
+ yield* execute(options.output, operation, challengeEvaluateText, evaluationErrorText);
61366
+ })).pipe(exports_Command.withDescription("Score a solution on hidden cases. Broken Agent requires participant browser approval before a limited evaluation is consumed."), exports_Command.withExamples([
61275
61367
  {
61276
61368
  command: "chofex challenge evaluate --challenge broken-agent --source ./scheduler.js --review ./review.json",
61277
61369
  description: "Consume una evaluación oficial cuando tu solución esté lista"
@@ -61332,7 +61424,7 @@ var challengeCommand = exports_Command.make("challenge", {}, exports_Effect.fn("
61332
61424
  return;
61333
61425
  }
61334
61426
  yield* exports_Console.log(challengeQuickstartText(participationState, launchNotice));
61335
- })).pipe(exports_Command.withDescription("Compite en challenges técnicos. Ejecuta el comando sin subcomandos para abrir la guía del challenge actual."), exports_Command.withExamples([
61427
+ })).pipe(exports_Command.withDescription("Compite en challenges técnicos obligatorios por un cupo. Ejecuta el comando sin subcomandos para abrir la guía del challenge actual."), exports_Command.withExamples([
61336
61428
  {
61337
61429
  command: "chofex challenge",
61338
61430
  description: "Abre la guía de Broken Agent"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chofex-cli",
3
- "version": "0.1.190",
3
+ "version": "0.1.191",
4
4
  "description": "Command-line client for Hack the Andes",
5
5
  "type": "module",
6
6
  "bin": {