@open-macaron/review 0.2.0 → 0.3.0

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 (2) hide show
  1. package/macaron-review.mjs +39 -8
  2. package/package.json +1 -1
@@ -21994,7 +21994,7 @@ var Usd = external_exports.number().nonnegative().max(1e3);
21994
21994
  // ../contracts/src/mode.ts
21995
21995
  var Mode = external_exports.enum(["triage", "plan", "implement", "address_review", "reproduce", "verify", "retro", "review"]);
21996
21996
  var Harness = external_exports.enum(["claude", "codex", "opencode"]);
21997
- var Capability = external_exports.enum(["gui", "video", "container"]);
21997
+ var Platform = external_exports.enum(["linux", "windows", "macos"]);
21998
21998
  var ResultAction = external_exports.enum(["reply", "plan", "ask", "commit", "escalate", "noop", "review"]);
21999
21999
 
22000
22000
  // ../contracts/src/config.ts
@@ -22039,6 +22039,8 @@ var Contribution = external_exports.strictObject({
22039
22039
  cla: external_exports.url().optional(),
22040
22040
  fixCi: external_exports.boolean()
22041
22041
  });
22042
+ var PlatformSettings = external_exports.strictObject({ runsOn: external_exports.string().min(1) });
22043
+ var OtherPlatform = Platform.exclude(["linux"]);
22042
22044
  var MAX_TIMEOUT_MINUTES = 360;
22043
22045
  var RepoSettings = external_exports.strictObject({
22044
22046
  harness: Harness,
@@ -22047,7 +22049,10 @@ var RepoSettings = external_exports.strictObject({
22047
22049
  models: external_exports.partialRecord(Mode, external_exports.string().min(1)),
22048
22050
  /** The harness's small background model (Claude Code's "haiku" slot). Names follow the LLM backend. */
22049
22051
  fastModel: external_exports.string().min(1),
22052
+ /** The Linux runner label. */
22050
22053
  runsOn: external_exports.string().min(1),
22054
+ /** The other platforms runs may ask for (`@macaron-bot reproduce on windows`). */
22055
+ platforms: external_exports.partialRecord(OtherPlatform, PlatformSettings).default({}),
22051
22056
  draftPr: external_exports.boolean(),
22052
22057
  timeoutMinutes: external_exports.int().min(5).max(MAX_TIMEOUT_MINUTES),
22053
22058
  /** USD per run, enforced by the run's LLM key. `review` is the ceiling of `reviewCost`. */
@@ -22056,7 +22061,6 @@ var RepoSettings = external_exports.strictObject({
22056
22061
  caps: Caps,
22057
22062
  environment: Environment,
22058
22063
  commands: Commands,
22059
- capabilities: external_exports.array(Capability),
22060
22064
  contribution: Contribution
22061
22065
  });
22062
22066
  var RepoSettingsPatch = external_exports.strictObject({
@@ -22065,6 +22069,7 @@ var RepoSettingsPatch = external_exports.strictObject({
22065
22069
  models: external_exports.partialRecord(Mode, external_exports.string().min(1)).optional(),
22066
22070
  fastModel: external_exports.string().min(1).optional(),
22067
22071
  runsOn: external_exports.string().min(1).optional(),
22072
+ platforms: external_exports.partialRecord(OtherPlatform, PlatformSettings.partial()).optional(),
22068
22073
  draftPr: external_exports.boolean().optional(),
22069
22074
  timeoutMinutes: external_exports.int().min(5).max(MAX_TIMEOUT_MINUTES).optional(),
22070
22075
  budgets: Budgets.partial().optional(),
@@ -22072,7 +22077,6 @@ var RepoSettingsPatch = external_exports.strictObject({
22072
22077
  caps: Caps.partial().optional(),
22073
22078
  environment: EnvironmentPatch.optional(),
22074
22079
  commands: Commands.optional(),
22075
- capabilities: external_exports.array(Capability).optional(),
22076
22080
  contribution: Contribution.partial().optional()
22077
22081
  });
22078
22082
  var GlobalFile = external_exports.strictObject({
@@ -22126,8 +22130,10 @@ var RuleFrontMatter = external_exports.strictObject({
22126
22130
  /** Where the rule comes from: review comments, documentation. */
22127
22131
  sources: external_exports.array(HttpsUrl).default([])
22128
22132
  });
22133
+ var LessonDescription = external_exports.string().min(1).max(1024);
22129
22134
  var LessonFrontMatter = external_exports.strictObject({
22130
22135
  topic: external_exports.string().min(1).max(120),
22136
+ description: LessonDescription.optional(),
22131
22137
  applies_to: external_exports.array(Glob).min(1).optional(),
22132
22138
  /** Evidence: a lesson without a source can't be reviewed. */
22133
22139
  sources: external_exports.array(HttpsUrl).min(1),
@@ -22151,6 +22157,7 @@ var PublishedLesson = external_exports.strictObject({
22151
22157
  id: external_exports.string().min(1),
22152
22158
  scope: KnowledgeScope,
22153
22159
  topic: external_exports.string(),
22160
+ description: LessonDescription.optional(),
22154
22161
  appliesTo: external_exports.array(Glob).nullable(),
22155
22162
  sources: external_exports.array(HttpsUrl),
22156
22163
  lastVerified: external_exports.iso.date(),
@@ -22176,7 +22183,7 @@ var KnowledgeIndex = external_exports.strictObject({
22176
22183
  /** Relative to the index, e.g. `projects/sandbox.json`. */
22177
22184
  path: external_exports.string(),
22178
22185
  rules: external_exports.array(PublishedRule.pick({ id: true, title: true, severity: true, appliesTo: true })),
22179
- lessons: external_exports.array(PublishedLesson.pick({ id: true, topic: true }))
22186
+ lessons: external_exports.array(PublishedLesson.pick({ id: true, topic: true, description: true }))
22180
22187
  })
22181
22188
  )
22182
22189
  });
@@ -22224,6 +22231,10 @@ var ReviewContext = external_exports.strictObject({
22224
22231
  /** open-macaron/knowledge commit the rules come from; null when no slice exists for the repo. */
22225
22232
  knowledgeCommit: CommitSha.nullable()
22226
22233
  });
22234
+ var RunKnowledge = external_exports.strictObject({
22235
+ commit: CommitSha.nullable(),
22236
+ lessons: external_exports.array(PublishedLesson).max(200)
22237
+ });
22227
22238
  var RunContext = external_exports.strictObject({
22228
22239
  mode: Mode,
22229
22240
  repo: RepoSlug,
@@ -22244,7 +22255,13 @@ var RunContext = external_exports.strictObject({
22244
22255
  commands: Commands,
22245
22256
  attachments: AttachmentLimits,
22246
22257
  /** Set iff mode is `review`. */
22247
- review: ReviewContext.optional()
22258
+ review: ReviewContext.optional(),
22259
+ /** The machine's operating system. Defaults keep contexts from controllers that predate platforms valid. */
22260
+ platform: Platform.default("linux"),
22261
+ /** The platforms this repository's runs can use: where a triage run may escalate to. */
22262
+ platforms: external_exports.array(Platform).min(1).default(["linux"]),
22263
+ /** Empty for reviews (they get rules, in `review`) and in contexts from controllers that predate it. */
22264
+ knowledge: RunKnowledge.default({ commit: null, lessons: [] })
22248
22265
  });
22249
22266
  var RuleVerdict = external_exports.strictObject({
22250
22267
  ruleId: external_exports.string().min(1).max(200),
@@ -22277,12 +22294,18 @@ var Reply = external_exports.strictObject({
22277
22294
  var Learning = external_exports.strictObject({
22278
22295
  scope: external_exports.enum(["global", "project", "repo"]),
22279
22296
  topic: external_exports.string().min(1).max(120),
22297
+ /** The lesson's skill description; the topic stands in for it when absent. */
22298
+ description: LessonDescription.optional(),
22280
22299
  text: external_exports.string().min(1).max(4096),
22281
- evidence: external_exports.url()
22300
+ evidence: external_exports.url(),
22301
+ /** The id of the lesson this revises (`<scope>/lessons/<slug>`), from `context.knowledge`. */
22302
+ updates: external_exports.string().min(1).max(300).optional()
22282
22303
  });
22283
22304
  var RunResult = external_exports.strictObject({
22284
22305
  action: ResultAction,
22285
22306
  escalateTo: Mode.optional(),
22307
+ /** The platform the escalated run should use; the escalating run's own when absent. */
22308
+ escalateOn: Platform.optional(),
22286
22309
  commitMessage: external_exports.string().min(1).max(4096).optional(),
22287
22310
  pr: external_exports.strictObject({ title: external_exports.string().min(1).max(256), body: Body }).optional(),
22288
22311
  message: Body.optional(),
@@ -22298,6 +22321,9 @@ var RunResult = external_exports.strictObject({
22298
22321
  if (result.action === "escalate" && result.escalateTo === void 0) {
22299
22322
  ctx.addIssue({ code: "custom", path: ["escalateTo"], message: "required when action is escalate" });
22300
22323
  }
22324
+ if (result.action !== "escalate" && result.escalateOn !== void 0) {
22325
+ ctx.addIssue({ code: "custom", path: ["escalateOn"], message: "only when action is escalate" });
22326
+ }
22301
22327
  if (result.action === "commit" && result.commitMessage === void 0) {
22302
22328
  ctx.addIssue({ code: "custom", path: ["commitMessage"], message: "required when action is commit" });
22303
22329
  }
@@ -22983,12 +23009,16 @@ var KnowledgeSource = class {
22983
23009
  baseUrl;
22984
23010
  cache = /* @__PURE__ */ new Map();
22985
23011
  async rules(options) {
23012
+ const { commit, rules } = await this.knowledge(options);
23013
+ return { commit, rules };
23014
+ }
23015
+ async knowledge(options) {
22986
23016
  const paths = ["global.json"];
22987
23017
  if (options.project !== void 0) paths.push(`projects/${options.project}.json`);
22988
23018
  if (options.repo !== void 0) paths.push(`repos/${options.repo}.json`);
22989
23019
  const slices = await Promise.all(paths.map((path) => this.slice(path)));
22990
23020
  const present = slices.filter((slice) => slice !== void 0);
22991
- return { commit: present.at(-1)?.commit ?? null, rules: present.flatMap((slice) => slice.rules) };
23021
+ return { commit: present.at(-1)?.commit ?? null, rules: present.flatMap((slice) => slice.rules), lessons: present.flatMap((slice) => slice.lessons) };
22992
23022
  }
22993
23023
  /** A missing slice (404) is a level without knowledge yet, not an error. */
22994
23024
  async slice(path) {
@@ -23002,7 +23032,8 @@ var KnowledgeSource = class {
23002
23032
  }
23003
23033
  if (!response.ok) throw new KnowledgeUnavailable(`${path}: HTTP ${String(response.status)}`, response.status);
23004
23034
  const parsed = KnowledgeSlice.safeParse(await response.json());
23005
- if (!parsed.success) throw new KnowledgeUnavailable(`${path}: not a knowledge slice`, response.status);
23035
+ if (!parsed.success) throw new KnowledgeUnavailable(`${path}: not a knowledge slice:
23036
+ ${external_exports.prettifyError(parsed.error)}`, response.status);
23006
23037
  const etag = response.headers.get("etag");
23007
23038
  if (etag !== null) this.cache.set(url2, { etag, slice: parsed.data });
23008
23039
  return parsed.data;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-macaron/review",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "macaron-bot's review engine: open-macaron/knowledge rules selected by changed files, checked by an agent in a read-only session, evidence verified. Used by the bot and, as the macaron-review CLI, locally.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",