pubuilder 0.5.0 → 0.7.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.
@@ -0,0 +1,28 @@
1
+ import type { AgentEvent } from './api';
2
+ import type { BlockSelection } from './types';
3
+ export type PublishStatus = 'idle' | 'running' | 'done' | 'error';
4
+ /**
5
+ * 한 블록의 퍼블리싱 job 상태. selection에 종속된 로컬 state가 아니라
6
+ * store에 블록별로 보관되어, 다른 블록을 선택해도 실행 중인 job이 끊기지 않는다.
7
+ */
8
+ export interface PublishJobState {
9
+ jobId: string | null;
10
+ status: PublishStatus;
11
+ events: AgentEvent[];
12
+ errorMessage: string | null;
13
+ errorCode: string | null;
14
+ serverDown: boolean;
15
+ /** isAlive/startPublish 왕복 중 로딩 플래그 */
16
+ checking: boolean;
17
+ cancelling: boolean;
18
+ /** 입력값도 블록별로 유지 — 전환 후 돌아와도 그대로 */
19
+ figmaUrl: string;
20
+ reply: string;
21
+ }
22
+ export declare const IDLE_PUBLISH_JOB: PublishJobState;
23
+ /**
24
+ * 블록을 페이지 간에도 고유하게 식별하는 키.
25
+ * 서로 다른 페이지가 같은 selector를 가질 수 있으므로 pagePath까지 합친다.
26
+ * '\n'은 selector/pagePath에 나타나지 않아 구분자로 안전하다.
27
+ */
28
+ export declare function blockKey(sel: BlockSelection): string;
@@ -1,6 +1,31 @@
1
+ /** 충돌 파일 정보: 사용자가 파일 단위로 revert/keep/edit 결정한다 */
2
+ export interface SuspendConflict {
3
+ file: string;
4
+ baseline: string;
5
+ current: string;
6
+ }
7
+ export interface SuspendResult {
8
+ autoReverted: string[];
9
+ conflicts: SuspendConflict[];
10
+ }
11
+ export type SuspendResolution = {
12
+ file: string;
13
+ action: 'revert' | 'keep' | 'edit';
14
+ content?: string;
15
+ };
16
+ /** 테스트에서 fs/git 없이 로직만 검증할 수 있도록 주입 가능한 파일 연산 */
17
+ interface SnapshotOps {
18
+ captureBaseline?: (cwd: string) => string | null;
19
+ readBaseline?: (cwd: string, ref: string, file: string) => string | null;
20
+ restoreFile?: (cwd: string, ref: string, file: string) => void;
21
+ readCurrent?: (cwd: string, file: string) => string;
22
+ writeFile?: (cwd: string, file: string, content: string) => void;
23
+ }
1
24
  export interface AgentEvent {
2
25
  type: 'log' | 'tool' | 'error' | 'done';
3
26
  text: string;
27
+ /** tool 이벤트에서 Edit/Write 대상 파일 경로 (touchedFiles 추적용) */
28
+ file?: string;
4
29
  }
5
30
  export interface AgentRunOptions {
6
31
  prompt: string;
@@ -18,13 +43,20 @@ export interface AgentAdapter {
18
43
  */
19
44
  export declare function parseAgentLine(line: string): AgentEvent[];
20
45
  export declare const claudeAdapter: AgentAdapter;
21
- /** 동시 실행 1개 제한 (스펙). 이벤트는 저장 후 브로드캐스트 — 늦은 SSE 구독자는 replay */
46
+ /** 이벤트는 저장 후 브로드캐스트 — 늦은 SSE 구독자는 replay */
22
47
  export declare class PublishJobManager {
23
48
  private readonly adapter;
24
49
  private jobs;
25
- private active;
26
50
  private seq;
27
- constructor(adapter: AgentAdapter);
51
+ private readonly capture;
52
+ private readonly readBaseline;
53
+ private readonly restoreFile;
54
+ private readonly readCurrent;
55
+ private readonly writeFile;
56
+ /** suspend 시 파일별 baseline ref를 보관 → resolve의 revert에서 사용 */
57
+ private pendingBaseline;
58
+ constructor(adapter: AgentAdapter, opts?: SnapshotOps);
59
+ private activeCount;
28
60
  start(opts: {
29
61
  prompt: string;
30
62
  cwd: string;
@@ -33,7 +65,24 @@ export declare class PublishJobManager {
33
65
  private evictFinishedJobs;
34
66
  /** SSE 핸들러가 헤더 전송 전에 job 존재를 확인할 때 사용 (subscribe는 replay 부작용이 있어 분리) */
35
67
  has(id: string): boolean;
68
+ /** job이 편집한 파일 목록 (상대경로, 정렬) */
69
+ touchedFiles(id: string): string[];
70
+ /** job 시작 시점 baseline ref */
71
+ baselineRef(id: string): string | null;
72
+ /**
73
+ * 진행 중(running)인 job을 전부 abort하고, 그들이 편집한 파일을 분류한다.
74
+ * - 자동 롤백: running job만 건드린 파일 → baseline으로 즉시 복원
75
+ * - 충돌: 완료(finished)된 job도 건드린 파일 → 사용자 해결 대상으로 반환
76
+ * 파일별 baseline은 그 파일을 건드린 running job 중 가장 이른(seq 최소) job의 것.
77
+ */
78
+ suspendRunning(cwd: string): SuspendResult;
79
+ /**
80
+ * 충돌 파일에 대한 사용자 결정을 적용한다.
81
+ * revert → baseline 복원, edit → content로 덮어쓰기, keep → 그대로 둔다.
82
+ */
83
+ applyResolutions(cwd: string, resolutions: SuspendResolution[]): void;
36
84
  subscribe(id: string, listener: (e: AgentEvent) => void): () => void;
37
85
  cancel(id: string): void;
38
86
  waitFor(id: string): Promise<void>;
39
87
  }
88
+ export {};
@@ -11,5 +11,7 @@ export interface PublishPromptInput {
11
11
  name: string;
12
12
  content: string;
13
13
  }>;
14
+ /** 에이전트의 확인 질문에 대한 사용자 후속 답변 */
15
+ instruction?: string;
14
16
  }
15
17
  export declare function buildPublishPrompt(input: PublishPromptInput): string;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 현재 작업 트리 상태를 커밋 오브젝트로 스냅샷하고 그 SHA를 반환한다.
3
+ * 워킹트리·stash 목록을 건드리지 않는다(`git stash create`).
4
+ * 트리가 clean이면 'HEAD'(동일 상태), 비-git이거나 실패하면 null(롤백 기능 degrade).
5
+ */
6
+ export declare function captureBaseline(cwd: string): string | null;
7
+ /** ref 시점의 file 내용. ref에 해당 파일이 없으면(스냅샷 이후 생성된 신규 파일) null. */
8
+ export declare function readBaseline(cwd: string, ref: string, file: string): string | null;
9
+ /** file을 baseline으로 복원한다. baseline에 없던(신규 생성) 파일이면 삭제한다. */
10
+ export declare function restoreFile(cwd: string, ref: string, file: string): void;
package/dist/store.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { AgentEvent, SuspendConflict, SuspendResolution } from './api';
2
+ import { type PublishJobState } from './publish-jobs';
1
3
  import type { BlockSelection, Granularity } from './types';
2
4
  interface PubuilderStore {
3
5
  isMapOpen: boolean;
@@ -9,6 +11,11 @@ interface PubuilderStore {
9
11
  /** 선택된 블록의 outerHTML 스냅샷 (Phase 3 퍼블리싱 프롬프트용, 20K 상한) */
10
12
  selectedOuterHTML: string | null;
11
13
  skillDrawerOpen: boolean;
14
+ /**
15
+ * 블록별 퍼블리싱 job 상태 (key: blockKey). selection에서 분리되어 있어
16
+ * 다른 블록을 선택하거나 맵을 닫아도 실행 중인 job이 끊기지 않는다.
17
+ */
18
+ publishJobs: Record<string, PublishJobState>;
12
19
  openMap: () => void;
13
20
  closeMap: () => void;
14
21
  openViewer: (path: string) => void;
@@ -17,6 +24,17 @@ interface PubuilderStore {
17
24
  setInspectEnabled: (v: boolean) => void;
18
25
  setSelectionWithHTML: (s: BlockSelection | null, html: string | null) => void;
19
26
  toggleSkillDrawer: () => void;
27
+ /** 블록 job의 일부 필드를 갱신 (없으면 IDLE에서 시작) */
28
+ patchPublishJob: (key: string, partial: Partial<PublishJobState>) => void;
29
+ /** 블록 job의 이벤트 로그에 한 건 추가 */
30
+ appendPublishEvent: (key: string, event: AgentEvent) => void;
31
+ /** 일시 종료 후 사용자가 해결해야 하는 충돌 파일들 (없으면 패널 미표시) */
32
+ suspendConflicts: SuspendConflict[];
33
+ /** 충돌 파일별 사용자 결정 (file → resolution) */
34
+ suspendResolutions: Record<string, SuspendResolution>;
35
+ setSuspendConflicts: (conflicts: SuspendConflict[]) => void;
36
+ setConflictResolution: (file: string, action: SuspendResolution['action'], content?: string) => void;
37
+ clearSuspend: () => void;
20
38
  }
21
39
  export declare const usePubuilderStore: import("zustand").UseBoundStore<import("zustand").StoreApi<PubuilderStore>>;
22
40
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pubuilder",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "In-app IA minimap & block inspector for React — live iframe thumbnails of every page, plus a Next.js route scanner that drafts your ia.config (dev-only)",
5
5
  "license": "MIT",
6
6
  "author": "taehoon",
@@ -38,7 +38,8 @@
38
38
  }
39
39
  },
40
40
  "files": [
41
- "dist"
41
+ "dist",
42
+ "CHANGELOG.md"
42
43
  ],
43
44
  "sideEffects": false,
44
45
  "scripts": {