@neriros/ralphy 3.10.12 → 3.10.14

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/dist/shell/index.js +37 -13
  2. package/package.json +1 -1
@@ -18928,8 +18928,8 @@ import { readFileSync } from "fs";
18928
18928
  import { resolve } from "path";
18929
18929
  function getVersion() {
18930
18930
  try {
18931
- if ("3.10.12")
18932
- return "3.10.12";
18931
+ if ("3.10.14")
18932
+ return "3.10.14";
18933
18933
  } catch {}
18934
18934
  const dirsToTry = [];
18935
18935
  try {
@@ -81281,7 +81281,7 @@ function foldLegacyAssignee(v) {
81281
81281
  }
81282
81282
  return rest2;
81283
81283
  }
81284
- var CURRENT_WORKFLOW_VERSION = 4, MarkerSchema, SET_INDICATOR_KEYS, GetIndicatorSchema, SetIndicatorSchema, IndicatorsSchema, ProjectSchema, CommandsSchema, DEFAULT_META_ONLY_FILES, BoundariesSchema, WorkflowConfigSchema;
81284
+ var CURRENT_WORKFLOW_VERSION = 5, MarkerSchema, SET_INDICATOR_KEYS, GetIndicatorSchema, SetIndicatorSchema, IndicatorsSchema, ProjectSchema, CommandsSchema, DEFAULT_META_ONLY_FILES, BoundariesSchema, WorkflowConfigSchema;
81285
81285
  var init_schema = __esm(() => {
81286
81286
  init_zod();
81287
81287
  MarkerSchema = exports_external.discriminatedUnion("type", [
@@ -81430,6 +81430,7 @@ var init_schema = __esm(() => {
81430
81430
  syncTasksToComment: exports_external.boolean().default(true),
81431
81431
  syncSpecsAsAttachments: exports_external.boolean().default(true),
81432
81432
  specAttachmentFormats: exports_external.array(exports_external.enum(["md", "pdf"])).nonempty().default(["md"]),
81433
+ specAttachmentRevisions: exports_external.enum(["append", "replace"]).default("replace"),
81433
81434
  confirmationMode: exports_external.object({
81434
81435
  enabled: exports_external.boolean().default(false),
81435
81436
  timeoutHours: exports_external.number().positive().default(48),
@@ -81451,6 +81452,7 @@ var init_schema = __esm(() => {
81451
81452
  syncTasksToComment: true,
81452
81453
  syncSpecsAsAttachments: true,
81453
81454
  specAttachmentFormats: ["md"],
81455
+ specAttachmentRevisions: "replace",
81454
81456
  confirmationMode: {
81455
81457
  enabled: false,
81456
81458
  timeoutHours: 48,
@@ -81605,6 +81607,8 @@ linear:
81605
81607
  syncTasksToComment: true
81606
81608
  syncSpecsAsAttachments: true
81607
81609
  specAttachmentFormats: ["md"]
81610
+ # replace (default): overwrite the canonical design attachment in place; append: keep each sealed change as a new "#N" attachment
81611
+ specAttachmentRevisions: replace
81608
81612
  indicators:
81609
81613
  # Indicators map Ralph lifecycle events to Linear labels/statuses. Within an
81610
81614
  # indicator's \`filter:\` list, entries of the SAME type are ORed and entries
@@ -84448,6 +84452,11 @@ var init_migrations = __esm(() => {
84448
84452
  version: 4,
84449
84453
  description: "A new additive `setPrReady` Linear indicator marks a ticket the moment its " + "PR is human-mergeable (ready, non-draft), layered on top of `setDone`. " + "Re-run the indicator builder to add it, or keep your current indicators.",
84450
84454
  fields: ["linear.indicators"]
84455
+ },
84456
+ {
84457
+ version: 5,
84458
+ description: "A new `linear.specAttachmentRevisions` setting controls the sealed " + "design attachment: 'replace' (default) overwrites the single canonical " + "attachment in place; 'append' publishes each change as a new " + "'Ralph design #N' attachment. Config-file-only \u2014 set it in WORKFLOW.md " + "if you want the append audit trail.",
84459
+ fields: []
84451
84460
  }
84452
84461
  ];
84453
84462
  LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max2, migration) => Math.max(max2, migration.version), 0);
@@ -103105,11 +103114,21 @@ function formatLinearError(err) {
103105
103114
  async function linearRequest(apiKey, query, variables) {
103106
103115
  let lastHttpError;
103107
103116
  for (let attempt2 = 1;attempt2 <= MAX_LINEAR_ATTEMPTS; attempt2++) {
103108
- const res = await fetch(LINEAR_API, {
103109
- method: "POST",
103110
- headers: { "Content-Type": "application/json", Authorization: apiKey },
103111
- body: JSON.stringify({ query, variables })
103112
- });
103117
+ let res;
103118
+ try {
103119
+ res = await fetch(LINEAR_API, {
103120
+ method: "POST",
103121
+ headers: { "Content-Type": "application/json", Authorization: apiKey },
103122
+ body: JSON.stringify({ query, variables })
103123
+ });
103124
+ } catch (netErr) {
103125
+ lastHttpError = netErr;
103126
+ if (attempt2 < MAX_LINEAR_ATTEMPTS) {
103127
+ await linearRequestInternals.sleep(Math.min(backoffMs(attempt2), MAX_RETRY_AFTER_MS));
103128
+ continue;
103129
+ }
103130
+ throw netErr;
103131
+ }
103113
103132
  if (!res.ok) {
103114
103133
  const err = new Error("Linear API request failed");
103115
103134
  err.status = res.status;
@@ -262041,11 +262060,15 @@ ${body}
262041
262060
  offset += p.length;
262042
262061
  }
262043
262062
  const hash2 = sha256Hex(sourceBytes);
262063
+ const designOnlyHash = sha256Hex(primaryBytes);
262044
262064
  const state = await readSpecAttachments(deps.statePath);
262045
- if (await isDesignSealed(stateDirOf(deps.statePath))) {
262046
- await syncSlotSealed(deps, slot, sourceBytes, hash2, state);
262065
+ const sealed = await isDesignSealed(stateDirOf(deps.statePath));
262066
+ const mode = deps.sealedRevisionMode ?? "append";
262067
+ if (sealed && mode === "append") {
262068
+ await syncSlotSealed(deps, slot, sourceBytes, designOnlyHash, state);
262047
262069
  return;
262048
262070
  }
262071
+ const skipHash = sealed ? designOnlyHash : hash2;
262049
262072
  let current = state[slot] ?? EMPTY_SLOT;
262050
262073
  if (!current.attachmentId) {
262051
262074
  const { adoptedId } = await adopt(deps, slot);
@@ -262053,7 +262076,7 @@ ${body}
262053
262076
  current = { attachmentId: adoptedId, sha256: null };
262054
262077
  }
262055
262078
  }
262056
- if (current.attachmentId && current.sha256 === hash2) {
262079
+ if (current.attachmentId && current.sha256 === skipHash) {
262057
262080
  deps.log(` spec-attachments: ${spec.uploadFilename} unchanged, skipping`, "gray");
262058
262081
  return;
262059
262082
  }
@@ -262101,7 +262124,7 @@ ${body}
262101
262124
  deps.log(`! spec-attachments: createAttachmentForUrl ${spec.uploadFilename} failed: ${describeLinearError(err)}`, "yellow");
262102
262125
  return;
262103
262126
  }
262104
- await persistSlot(deps.statePath, slot, { attachmentId: newId, sha256: hash2 });
262127
+ await persistSlot(deps.statePath, slot, { attachmentId: newId, sha256: skipHash });
262105
262128
  deps.log(` spec-attachments: created ${spec.uploadFilename} attachment`, "gray");
262106
262129
  }
262107
262130
  async function purgeLegacyProposalSlots(deps) {
@@ -262245,7 +262268,8 @@ function createCommentSyncHooks(input) {
262245
262268
  iteration,
262246
262269
  log: onLog,
262247
262270
  mutations: specAttachmentMutations,
262248
- formats: cfg.linear.specAttachmentFormats
262271
+ formats: cfg.linear.specAttachmentFormats,
262272
+ sealedRevisionMode: cfg.linear.specAttachmentRevisions
262249
262273
  });
262250
262274
  }
262251
262275
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neriros/ralphy",
3
- "version": "3.10.12",
3
+ "version": "3.10.14",
4
4
  "description": "An iterative AI task execution framework. Orchestrates multi-phase autonomous work using Claude or Codex engines.",
5
5
  "keywords": [
6
6
  "agent",