@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.
- package/index.mjs +122 -35
- 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.
|
|
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.
|
|
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}
|
|
2039
|
+
"gitControls.pullAria": "{branch} 브랜치 pull",
|
|
2012
2040
|
"gitControls.pullTitle": "{branch} pull",
|
|
2013
|
-
"gitControls.pushAria": "{branch}
|
|
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
|
|
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:
|
|
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
|
|
20278
|
-
const path = worktreePath
|
|
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);
|