@buzzni/saycode-cli 0.3.0 → 0.3.1

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/index.mjs +122 -35
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -40,7 +40,7 @@ function _mergeNamespaces(n, m) {
40
40
  }
41
41
  return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
42
42
  }
43
- const version = "0.3.0";
43
+ const version = "0.3.1";
44
44
  const manifest = {
45
45
  version
46
46
  };
@@ -622,8 +622,30 @@ const scheduledAutomationsKo = {
622
622
  "scheduledAutomations.scheduleDaily": "매일 지정 시각",
623
623
  "scheduledAutomations.intervalMinutesLabel": "실행 주기(분, 최소 {min}분)",
624
624
  "scheduledAutomations.dailyTimeLabel": "실행 시각",
625
- "scheduledAutomations.scriptLabel": "감시 스크립트 커맨드 (선택)",
625
+ "scheduledAutomations.monitorLabel": "변화 감지 커맨드 (선택)",
626
+ "scheduledAutomations.executionConditionLabel": "실행 조건",
627
+ "scheduledAutomations.executionEverySchedule": "예약마다 실행",
628
+ "scheduledAutomations.executionOnChange": "감시 결과가 바뀔 때만 실행",
629
+ "scheduledAutomations.advancedOptions": "고급 옵션 보기",
630
+ "scheduledAutomations.changeDetectionBadge": "변화 감지",
631
+ "scheduledAutomations.executionDetails": "실행 상세",
632
+ "scheduledAutomations.lastChange": "마지막 변화: {time}",
633
+ "scheduledAutomations.monitorOutputTitle": "최근 감시 출력",
634
+ "scheduledAutomations.monitorRequired": "변화 감지 명령을 입력하세요.",
635
+ "scheduledAutomations.templateLabel": "시작 템플릿",
636
+ "scheduledAutomations.templateNone": "직접 설정",
637
+ "scheduledAutomations.templateService": "서비스 상태 변화",
638
+ "scheduledAutomations.templateCommand": "명령 출력 변화",
639
+ "scheduledAutomations.templateHint": "템플릿은 폼만 채웁니다. 명령을 입력하고 확인한 뒤 직접 저장하세요.",
640
+ "scheduledAutomations.templateServiceName": "서비스 상태 감시",
641
+ "scheduledAutomations.templateCommandName": "명령 출력 감시",
642
+ "scheduledAutomations.templateServicePrompt": "서비스 상태가 어떻게 바뀌었는지 분석하고 필요한 조치를 제안해줘.",
643
+ "scheduledAutomations.templateCommandPrompt": "명령 출력의 변화를 분석하고 중요한 차이와 필요한 조치를 알려줘.",
644
+ "scheduledAutomations.monitorHint": "출력이 이전 성공 실행과 정확히 같으면 gate와 세션 실행을 생략합니다.",
645
+ "scheduledAutomations.notepadTitle": "자동화 메모장",
646
+ "scheduledAutomations.scriptLabel": "실행 gate 커맨드 (선택)",
626
647
  "scheduledAutomations.scriptHint": '마지막 줄이 {"wakeAgent": false} JSON이면 세션을 깨우지 않습니다.',
648
+ "scheduledAutomations.scriptHintFallback": '마지막 줄 JSON의 {"wakeAgent": false}는 세션을 깨우지 않고, {"notepad": {"key": "value"}}는 읽기 전용 메모장을 갱신합니다.',
627
649
  "scheduledAutomations.scriptWarning": "이 커맨드는 프로젝트 머신에서 사용자 권한으로 실행됩니다.",
628
650
  "scheduledAutomations.suppressSilentLabel": "응답이 [SILENT]면 알림 배지 생략",
629
651
  "scheduledAutomations.save": "저장",
@@ -637,6 +659,7 @@ const scheduledAutomationsKo = {
637
659
  "scheduledAutomations.nextRun": "다음 실행: {time}",
638
660
  "scheduledAutomations.historyTitle": "최근 실행",
639
661
  "scheduledAutomations.outcomeWoke": "세션 실행",
662
+ "scheduledAutomations.outcomeNoChange": "모니터 변화 없음(스킵)",
640
663
  "scheduledAutomations.outcomeSkippedGate": "변화 없음(스킵)",
641
664
  "scheduledAutomations.outcomeSkippedOverlap": "이전 실행 진행 중(스킵)",
642
665
  "scheduledAutomations.outcomeSilent": "이상 없음([SILENT])",
@@ -656,6 +679,7 @@ const scheduledAutomationsKo = {
656
679
  "scheduledAutomations.errorViewerKeyInUse": "기존 DB 자동화가 다른 암호화 키를 사용하고 있어 자동으로 전환할 수 없습니다. 기존 DB 자동화를 삭제한 뒤 다시 시도하세요.",
657
680
  "scheduledAutomations.errorWorkspaceMissing": "프로젝트 작업 폴더를 찾을 수 없습니다.",
658
681
  "scheduledAutomations.errorMachineOffline": "프로젝트 머신이 오프라인입니다.",
682
+ "scheduledAutomations.errorMonitorUnsupported": "대상 daemon이 변화 감지 자동화를 지원하지 않습니다. 연결 상태를 확인한 뒤 다시 시도하세요.",
659
683
  "scheduledAutomations.errorUnavailable": "자동화 서비스를 현재 사용할 수 없습니다.",
660
684
  "scheduledAutomations.runNow": "바로 실행",
661
685
  "scheduledAutomations.runRequestedNotice": "자동화 실행을 요청했습니다."
@@ -2000,6 +2024,10 @@ const ko = {
2000
2024
  "worktreePathCopy.copy": "worktree 경로 복사",
2001
2025
  "worktreePathCopy.copied": "worktree 경로 복사됨",
2002
2026
  "worktreePathCopy.failed": "worktree 경로 복사 실패",
2027
+ "sessionWorktree.worktree": "워크트리: {name}",
2028
+ "sessionWorktree.branch": "브랜치: {branch}",
2029
+ "sessionWorktree.path": "경로: {path}",
2030
+ "sessionWorktree.merged": "병합됨",
2003
2031
  // Project git controls
2004
2032
  "gitControls.branchLoading": "Git branch 확인 중",
2005
2033
  "gitControls.noRemote": "origin remote 또는 branch를 찾을 수 없습니다.",
@@ -2008,9 +2036,9 @@ const ko = {
2008
2036
  "gitControls.manageBranchAria": "{branch} branch 관리",
2009
2037
  "gitControls.manageBranchTitle": "Branch 변경 및 생성",
2010
2038
  "gitControls.manageBranchTitleWithDesc": "Branch 변경 및 생성 · {description}",
2011
- "gitControls.pullAria": "{branch} branch pull",
2039
+ "gitControls.pullAria": "{branch} 브랜치 pull",
2012
2040
  "gitControls.pullTitle": "{branch} pull",
2013
- "gitControls.pushAria": "{branch} branch push",
2041
+ "gitControls.pushAria": "{branch} 브랜치 push",
2014
2042
  "gitControls.pushTitle": "{branch} push",
2015
2043
  "gitControls.manageWorktreeAria": "{name} worktree 관리",
2016
2044
  "gitControls.manageWorktreeTitle": "Worktree 관리",
@@ -2733,6 +2761,8 @@ const ko = {
2733
2761
  "standaloneImport.doneSummary": "프로젝트 {projects}개, 세션 {sessions}개를 가져왔어요.",
2734
2762
  "standaloneImport.doneSkipped": "이미 가져온 세션 {count}개는 건너뛰었어요.",
2735
2763
  "standaloneImport.undecryptable": "복호화할 수 없어 건너뛴 메시지가 {count}개 있어요.",
2764
+ "standaloneImport.undecryptableMetadata": "세션 {count}개의 메타데이터 또는 에이전트 상태를 복호화하지 못해 일부 상태 없이 가져왔어요.",
2765
+ "standaloneImport.failedProjects": "프로젝트 {count}개를 가져오지 못했어요. 가능한 세션은 프로젝트 연결 없이 가져왔어요.",
2736
2766
  "standaloneImport.failedSessions": "세션 {count}개를 가져오지 못했어요. 다시 실행하면 이어서 시도해요.",
2737
2767
  "standaloneImport.fatalError": "가져오기를 시작하지 못했어요: {error}",
2738
2768
  "standaloneImport.settingsBody": "이 컴퓨터의 로컬 전용 모드 데이터를 현재 계정으로 복사해요.",
@@ -3211,6 +3241,8 @@ const ko = {
3211
3241
  "sessionsTab.searchFailed": "사용자 프롬프트를 검색하지 못했습니다. 제목 검색 결과만 표시합니다.",
3212
3242
  "sessionsTab.noSearchResults": "“{query}”와 일치하는 대화가 없습니다.",
3213
3243
  "sessionsTab.clearSearch": "검색 지우기",
3244
+ "sessionsTab.noVisibleMessage": "표시할 메시지가 아직 없습니다",
3245
+ "sessionsTab.updated": "업데이트",
3214
3246
  // Planning / preview sidecar / preview tab
3215
3247
  "previewSidecar.closeAria": "Preview 닫기",
3216
3248
  "preview.serverStarting": "서버 시작 중...",
@@ -3284,6 +3316,8 @@ const ko = {
3284
3316
  "saycodePromptPreference.block.axBase.description": "AX 워크플로우의 기본 지시를 사용합니다.",
3285
3317
  "saycodePromptPreference.block.coAuthoredCredit.label": "커밋 크레딧",
3286
3318
  "saycodePromptPreference.block.coAuthoredCredit.description": "커밋 메시지에 Claude와 Happy 공동 작성자 표시를 추가합니다.",
3319
+ "saycodePromptPreference.block.inlinePreview.label": "결과물 인라인 미리보기",
3320
+ "saycodePromptPreference.block.inlinePreview.description": "HTML 결과물을 만들면 답변 안에 미리보기를 띄우도록 지시합니다.",
3287
3321
  "saycodePromptPreference.loading": "계정 설정을 불러오는 중…",
3288
3322
  "standalone.zrokStatus": "zrok 상태",
3289
3323
  "standalone.zrokNeeded": "zrok2 설정이 필요합니다",
@@ -3834,6 +3868,7 @@ const ko = {
3834
3868
  "review.self.loopStop": "반복 중지",
3835
3869
  "review.self.loopDismiss": "기록 지우기",
3836
3870
  "review.self.loopDone": "반복 리뷰 종료 ({rounds}회) — {reason}",
3871
+ "review.self.startCancelled": "다른 창의 작업으로 반복 리뷰 시작이 취소됐어요.",
3837
3872
  "review.self.loopReason.clean": "지적 없음",
3838
3873
  "review.self.loopReason.belowThreshold": "low·nit만 남아 조기 종료",
3839
3874
  "review.self.loopReason.roundsExhausted": "지정한 횟수를 모두 사용",
@@ -16068,11 +16103,15 @@ function readMcpCallerGrantPublicKey(daemonState) {
16068
16103
  const value2 = daemonState.mcpCallerGrantPublicKey;
16069
16104
  return typeof value2 === "string" && value2 ? value2 : void 0;
16070
16105
  }
16071
- function buildWorktreeMutationBody(input) {
16106
+ function buildWorktreeMutationBody(input, options = {}) {
16072
16107
  return JSON.stringify(Object.fromEntries(
16073
- Object.entries(input).filter(([, value2]) => typeof value2 === "string" && value2.length > 0)
16108
+ Object.entries(input).filter(([key, value2]) => (key !== "machinePlatform" || options.includeMachinePlatform) && (typeof value2 === "string" && (value2.length > 0 || key === "branch") || key === "branch" && value2 === null))
16074
16109
  ));
16075
16110
  }
16111
+ const STANDALONE_USER_ID = "standalone-local";
16112
+ function isStandaloneAuthSession(session) {
16113
+ return session?.userId === STANDALONE_USER_ID;
16114
+ }
16076
16115
  function indexMachineRegistry(entries) {
16077
16116
  const byId = {};
16078
16117
  for (const entry of entries) {
@@ -16137,6 +16176,17 @@ function resolvedProjectPreviewRelayUrl(input) {
16137
16176
  }
16138
16177
  return `${input.syncBaseUrl}/v1/preview/${encodeURIComponent(input.machineId)}/${input.port}/?ptoken=${encodeURIComponent(response.token)}`;
16139
16178
  }
16179
+ const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
16180
+ function versionedAutomationBase64(value2, maxBytes, exactBytes) {
16181
+ if (typeof value2 !== "string" || !value2 || value2.length > Math.ceil(maxBytes / 3) * 4 || !BASE64_PATTERN.test(value2)) {
16182
+ throw new Error("automation-response-invalid");
16183
+ }
16184
+ const decoded = Buffer$1.from(value2, "base64");
16185
+ if (decoded.length < 41 || decoded.length > maxBytes || exactBytes !== void 0 && decoded.length !== exactBytes || decoded[0] !== 1) {
16186
+ throw new Error("automation-response-invalid");
16187
+ }
16188
+ return value2;
16189
+ }
16140
16190
  function row(value2) {
16141
16191
  if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) throw new Error("automation-response-invalid");
16142
16192
  return value2;
@@ -16158,10 +16208,23 @@ function nullableInteger(value2) {
16158
16208
  function optionalNullableInteger(value2) {
16159
16209
  return value2 === void 0 ? null : nullableInteger(value2);
16160
16210
  }
16161
- function parseServerAutomationPublic(value2) {
16211
+ function parseRuntimeState(value2) {
16162
16212
  const item = row(value2);
16163
- if (item.payloadVersion !== 1 || typeof item.paused !== "boolean") throw new Error("automation-response-invalid");
16164
16213
  return {
16214
+ automationId: stringValue(item.automationId),
16215
+ generation: integer(item.generation, 1),
16216
+ stateVersion: integer(item.stateVersion, 1),
16217
+ stateCiphertext: versionedAutomationBase64(item.stateCiphertext, 96 * 1024),
16218
+ viewerKeyVersion: integer(item.viewerKeyVersion, 1),
16219
+ viewerKeyEnvelope: versionedAutomationBase64(item.viewerKeyEnvelope, 105, 105),
16220
+ machineKeyVersion: integer(item.machineKeyVersion, 1),
16221
+ updatedAt: integer(item.updatedAt)
16222
+ };
16223
+ }
16224
+ function parseServerAutomationPublic(value2) {
16225
+ const item = row(value2);
16226
+ if (item.payloadVersion !== 1 && item.payloadVersion !== 2 || typeof item.paused !== "boolean") throw new Error("automation-response-invalid");
16227
+ const parsed = {
16165
16228
  id: stringValue(item.id),
16166
16229
  projectId: stringValue(item.projectId),
16167
16230
  ownerAccountId: stringValue(item.ownerAccountId),
@@ -16169,7 +16232,7 @@ function parseServerAutomationPublic(value2) {
16169
16232
  machineId: nullableString(item.machineId),
16170
16233
  revision: integer(item.revision, 1),
16171
16234
  generation: integer(item.generation, 1),
16172
- payloadVersion: 1,
16235
+ payloadVersion: item.payloadVersion,
16173
16236
  payloadCiphertext: stringValue(item.payloadCiphertext),
16174
16237
  viewerKeyId: stringValue(item.viewerKeyId),
16175
16238
  viewerKeyVersion: integer(item.viewerKeyVersion, 1),
@@ -16181,8 +16244,13 @@ function parseServerAutomationPublic(value2) {
16181
16244
  appliedRevision: integer(item.appliedRevision),
16182
16245
  appliedAt: nullableInteger(item.appliedAt),
16183
16246
  createdAt: integer(item.createdAt),
16184
- updatedAt: integer(item.updatedAt)
16247
+ updatedAt: integer(item.updatedAt),
16248
+ runtimeState: item.runtimeState === void 0 || item.runtimeState === null ? null : parseRuntimeState(item.runtimeState)
16185
16249
  };
16250
+ if (parsed.payloadVersion === 2 !== (parsed.runtimeState !== null) || parsed.runtimeState && (parsed.runtimeState.automationId !== parsed.id || parsed.runtimeState.generation !== parsed.generation || parsed.runtimeState.viewerKeyVersion !== parsed.viewerKeyVersion || parsed.runtimeState.machineKeyVersion !== parsed.machineKeyVersion)) {
16251
+ throw new Error("automation-response-invalid");
16252
+ }
16253
+ return parsed;
16186
16254
  }
16187
16255
  function parseServerAutomationAdoption(value2) {
16188
16256
  const item = row(value2);
@@ -16203,11 +16271,12 @@ function parseServerAutomationTarget(value2) {
16203
16271
  machinePublicKey: stringValue(item.machinePublicKey),
16204
16272
  machineKeyVersion: integer(item.machineKeyVersion, 1),
16205
16273
  viewerPublicKey: nullableString(item.viewerPublicKey),
16206
- viewerKeyVersion: integer(item.viewerKeyVersion)
16274
+ viewerKeyVersion: integer(item.viewerKeyVersion),
16275
+ automationProtocolVersion: item.automationProtocolVersion === void 0 ? 1 : integer(item.automationProtocolVersion, 1)
16207
16276
  };
16208
16277
  }
16209
16278
  const RUN_STATUSES = /* @__PURE__ */ new Set(["CLAIMED", "RUNNING", "COMPLETED", "FAILED", "CANCELLED", "EXPIRED", "ABANDONED"]);
16210
- const RUN_OUTCOMES = /* @__PURE__ */ new Set(["WOKE", "SILENT", "SKIPPED_GATE", "ERROR"]);
16279
+ const RUN_OUTCOMES = /* @__PURE__ */ new Set(["WOKE", "SILENT", "SKIPPED_GATE", "NO_CHANGE", "ERROR"]);
16211
16280
  function parseServerAutomationRun(value2) {
16212
16281
  const item = row(value2);
16213
16282
  if (!RUN_STATUSES.has(item.status) || item.outcome !== null && !RUN_OUTCOMES.has(item.outcome) || typeof item.lateReport !== "boolean") throw new Error("automation-response-invalid");
@@ -16463,6 +16532,7 @@ function normalizeAutomationSupport(value2) {
16463
16532
  return {
16464
16533
  rpcAvailable: capability.rpcAvailable,
16465
16534
  serverBacked: capability.serverBacked === true,
16535
+ ...typeof capability.monitorMode === "boolean" ? { monitorMode: capability.monitorMode } : {},
16466
16536
  ...Number.isSafeInteger(capability.keyVersion) && capability.keyVersion > 0 ? { keyVersion: capability.keyVersion } : {}
16467
16537
  };
16468
16538
  }
@@ -16506,7 +16576,8 @@ class ApiClient {
16506
16576
  apiBaseUrl: session.apiBaseUrl,
16507
16577
  syncBaseUrl: session.happyBaseUrl,
16508
16578
  apiToken: session.token,
16509
- syncToken: session.syncToken || session.token
16579
+ syncToken: session.syncToken || session.token,
16580
+ standalone: isStandaloneAuthSession(session)
16510
16581
  });
16511
16582
  }
16512
16583
  async login(input) {
@@ -17585,7 +17656,7 @@ class ApiClient {
17585
17656
  {
17586
17657
  method: "POST",
17587
17658
  boundary: "api",
17588
- body: buildWorktreeMutationBody(input)
17659
+ body: buildWorktreeMutationBody(input, { includeMachinePlatform: this.config.standalone })
17589
17660
  }
17590
17661
  );
17591
17662
  return data.worktree;
@@ -20216,6 +20287,22 @@ class ChatInputController {
20216
20287
  this.readline.off("close", this.handleClose);
20217
20288
  }
20218
20289
  }
20290
+ const MACOS_FIRMLINK_ALIASES = [
20291
+ ["/tmp", "/private/tmp"],
20292
+ ["/var", "/private/var"],
20293
+ ["/etc", "/private/etc"]
20294
+ ];
20295
+ function canonicalizeMacOsFirmlinkAlias(path) {
20296
+ for (const [logical, physical] of MACOS_FIRMLINK_ALIASES) {
20297
+ if (path === logical) return physical;
20298
+ if (path.startsWith(`${logical}/`)) return physical + path.slice(logical.length);
20299
+ }
20300
+ return path;
20301
+ }
20302
+ function canonicalizeRemotePathForComparison(value2, platform2) {
20303
+ const normalized = value2.trim().replace(/\/+$/, "");
20304
+ return platform2 === "darwin" ? canonicalizeMacOsFirmlinkAlias(normalized) : normalized;
20305
+ }
20219
20306
  function worktreeTargetMismatch(record2, expected) {
20220
20307
  if (record2.projectId !== expected.projectId) return "project";
20221
20308
  if (record2.machineId !== expected.machineId) return "machine";
@@ -20273,32 +20360,15 @@ function resolveWorktreeName(input) {
20273
20360
  }
20274
20361
  const MANAGED_WORKTREE_SEGMENT = "/.aplus/worktrees/";
20275
20362
  const MAX_MANAGED_WORKTREE_DEPTH = 2;
20276
- function isWorktreePathWithinProjectRoot(projectRoot, worktreePath) {
20277
- const root = projectRoot.trim().replace(/\/+$/, "");
20278
- const path = worktreePath.trim().replace(/\/+$/, "");
20363
+ function isWorktreePathWithinProjectRoot(projectRoot, worktreePath, platform2) {
20364
+ const root = canonicalizeRemotePathForComparison(projectRoot, platform2);
20365
+ const path = canonicalizeRemotePathForComparison(worktreePath, platform2);
20279
20366
  if (!root || !path) return false;
20280
20367
  if (!path.startsWith(`${root}${MANAGED_WORKTREE_SEGMENT}`)) return false;
20281
20368
  const segments = path.slice(root.length + MANAGED_WORKTREE_SEGMENT.length).split("/");
20282
20369
  if (segments.length < 1 || segments.length > MAX_MANAGED_WORKTREE_DEPTH) return false;
20283
20370
  return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
20284
20371
  }
20285
- async function createWorktreeOnMachine(input) {
20286
- const record2 = await input.client.createProjectWorktree(input.projectId, {
20287
- name: input.name,
20288
- baseRef: input.baseRef,
20289
- machineId: input.machineId,
20290
- ...input.confirmRepoRoot ? { confirmRepoRoot: input.confirmRepoRoot } : {}
20291
- });
20292
- const targetMismatch = worktreeTargetMismatch(record2, {
20293
- projectId: input.projectId,
20294
- machineId: input.machineId
20295
- });
20296
- const allowedRoot = input.confirmRepoRoot ?? input.repoCwd;
20297
- const pathMatches = isWorktreePathWithinProjectRoot(allowedRoot, record2.path);
20298
- if (!targetMismatch && pathMatches) return record2;
20299
- await input.client.deleteProjectWorktree(input.projectId, record2.id, true).catch(() => void 0);
20300
- throw new Error(!pathMatches && input.pathMismatchMessage ? input.pathMismatchMessage(record2.path) : input.targetMismatchMessage);
20301
- }
20302
20372
  const WORKTREE_SUBDIR_CONFIRM_CODE = "worktree-subdir-confirm-required";
20303
20373
  function trimmedString(value2) {
20304
20374
  if (typeof value2 !== "string") return null;
@@ -20338,6 +20408,23 @@ function parseWorktreeSubdirConfirmRequest(status, body, projectRoot) {
20338
20408
  if (!isSafeRelativeDir(repoRelativeDir)) return null;
20339
20409
  return { repoRoot, workspaceDir, repoRelativeDir };
20340
20410
  }
20411
+ async function createWorktreeOnMachine(input) {
20412
+ const record2 = await input.client.createProjectWorktree(input.projectId, {
20413
+ name: input.name,
20414
+ baseRef: input.baseRef,
20415
+ machineId: input.machineId,
20416
+ ...input.confirmRepoRoot ? { confirmRepoRoot: input.confirmRepoRoot } : {}
20417
+ });
20418
+ const targetMismatch = worktreeTargetMismatch(record2, {
20419
+ projectId: input.projectId,
20420
+ machineId: input.machineId
20421
+ });
20422
+ const allowedRoot = input.confirmRepoRoot ?? input.repoCwd;
20423
+ const pathMatches = isWorktreePathWithinProjectRoot(allowedRoot, record2.path, input.machinePlatform);
20424
+ if (!targetMismatch && pathMatches) return record2;
20425
+ await input.client.deleteProjectWorktree(input.projectId, record2.id, true).catch(() => void 0);
20426
+ throw new Error(!pathMatches && input.pathMismatchMessage ? input.pathMismatchMessage(record2.path) : input.targetMismatchMessage);
20427
+ }
20341
20428
  async function createCliProjectWorktree(input, deps) {
20342
20429
  const createInput = {
20343
20430
  client: {
@@ -23827,7 +23914,7 @@ function readFileOrNull(path) {
23827
23914
  async function recentContents(context, transport, sessionId, limit) {
23828
23915
  const messages = await context.rest.recentMessages(sessionId, limit);
23829
23916
  const contents = [];
23830
- for (const message of messages) {
23917
+ for (const message of [...messages].sort((left, right) => left.seq - right.seq)) {
23831
23918
  const ciphertext = unwrapEncryptedField(message.content);
23832
23919
  if (!ciphertext) continue;
23833
23920
  const content = decodeContent(transport, ciphertext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buzzni/saycode-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Drive Saycode sessions across your machines from the terminal.",
5
5
  "type": "module",
6
6
  "bin": {