@feedmepos/mf-miniprogram-v2 0.1.0-dev.24 → 0.1.0-dev.26

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/dist/app.js CHANGED
@@ -3,7 +3,7 @@ const n = [
3
3
  {
4
4
  path: "/",
5
5
  name: "miniprogram-v2-control",
6
- component: () => import("./ControlPlaneView-DVeW58te.js")
6
+ component: () => import("./ControlPlaneView-BBd62o75.js")
7
7
  },
8
8
  {
9
9
  path: "/:pathMatch(.*)*",
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feedmepos/mf-miniprogram-v2",
3
- "version": "0.1.0-dev.24",
3
+ "version": "0.1.0-dev.26",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@feedmepos/mf-common": "^1.27.9",
41
41
  "@feedmepos/ui-library": "1.8.4",
42
- "@opencode-ai/sdk": "*",
42
+ "@opencode-ai/sdk": "1.17.14",
43
43
  "diff": "^9.0.0",
44
44
  "dompurify": "^3.4.11",
45
45
  "highlight.js": "^11.11.1",
@@ -1,7 +1,13 @@
1
1
  import type { ChatMessage } from '../composables/types';
2
2
  type __VLS_Props = {
3
3
  message: ChatMessage;
4
+ canUndo?: boolean;
5
+ undoing?: boolean;
4
6
  };
5
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
+ undo: () => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onUndo?: (() => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
12
  declare const _default: typeof __VLS_export;
7
13
  export default _default;
@@ -0,0 +1,22 @@
1
+ import type { QuickEditOption } from '../composables/quickEdit';
2
+ type __VLS_Props = {
3
+ label: string;
4
+ /** `T|R|B|L`; an empty segment means that side is not set by any class. */
5
+ value: string;
6
+ options: QuickEditOption[];
7
+ invalid?: string | null;
8
+ /**
9
+ * Effective value from the cascade, shown when no class sets this group.
10
+ * Deliberately NOT named `computed`: <script setup> exposes imported bindings
11
+ * to the template, so a prop of that name is shadowed by Vue's own `computed`
12
+ * import and the template renders the function's source instead.
13
+ */
14
+ cascade?: string;
15
+ };
16
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
17
+ change: (value: string) => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
19
+ onChange?: ((value: string) => any) | undefined;
20
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -0,0 +1,20 @@
1
+ import type { QuickEditField, QuickEditFieldStatus, QuickEditValue } from '../composables/quickEdit';
2
+ type __VLS_Props = {
3
+ prop: string;
4
+ field: QuickEditField;
5
+ value: QuickEditValue;
6
+ status?: QuickEditFieldStatus;
7
+ invalid?: string | null;
8
+ hint?: string | null;
9
+ uploading?: boolean;
10
+ uploadDisabled?: boolean;
11
+ };
12
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
13
+ change: (value: QuickEditValue) => any;
14
+ "pick-image": (file: File) => any;
15
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
16
+ onChange?: ((value: QuickEditValue) => any) | undefined;
17
+ "onPick-image"?: ((file: File) => any) | undefined;
18
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
@@ -1,6 +1,10 @@
1
1
  import { type QuickEditFieldStatus, type QuickEditSelection, type QuickEditValue } from '../composables/quickEdit';
2
2
  type __VLS_Props = {
3
3
  selection: QuickEditSelection;
4
+ /** Innermost-first candidate path from one click; drives the path selector. */
5
+ targets?: QuickEditSelection[];
6
+ /** Index of the entry currently shown, so the path can mark it. */
7
+ activeTarget?: number;
4
8
  statuses: Record<string, QuickEditFieldStatus>;
5
9
  reasons: Record<string, string>;
6
10
  busy?: boolean;
@@ -14,6 +18,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
14
18
  }) => any;
15
19
  confirm: () => any;
16
20
  cancel: () => any;
21
+ retarget: (index: number) => any;
22
+ "preview-target": (index: number | null) => any;
17
23
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
18
24
  onChange?: ((payload: {
19
25
  prop: string;
@@ -21,6 +27,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
21
27
  }) => any) | undefined;
22
28
  onConfirm?: (() => any) | undefined;
23
29
  onCancel?: (() => any) | undefined;
30
+ onRetarget?: ((index: number) => any) | undefined;
31
+ "onPreview-target"?: ((index: number | null) => any) | undefined;
24
32
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
33
  declare const _default: typeof __VLS_export;
26
34
  export default _default;
@@ -1,4 +1,7 @@
1
- export type QuickEditControl = 'text' | 'textarea' | 'image' | 'color' | 'select' | 'number' | 'boolean';
1
+ import { type QuickEditClassGroupId, type QuickEditClassSection } from './quickEditClasses.ts';
2
+ export type QuickEditControl = 'text' | 'textarea' | 'image' | 'color' | 'select' | 'number' | 'boolean'
3
+ /** Four-side padding/margin editor; value is the `T|R|B|L` encoding. */
4
+ | 'box';
2
5
  export interface QuickEditOption {
3
6
  value: string;
4
7
  label: string;
@@ -13,16 +16,36 @@ export interface QuickEditField {
13
16
  min?: number;
14
17
  max?: number;
15
18
  step?: number;
19
+ /** Which Appearance subsection a style pseudo-field belongs to. */
20
+ section?: QuickEditClassSection;
21
+ /** Effective value from the cascade, shown when the group is unset. */
22
+ computed?: string;
23
+ /** Tailwind arbitrary-value example, e.g. `[15px]`. */
24
+ arbitraryHint?: string;
16
25
  }
17
26
  export type QuickEditValue = string | number | boolean;
18
27
  export type QuickEditLocate = 'usage-site' | 'component-own' | 'ambiguous-vfor';
28
+ export type QuickEditTargetKind = 'component' | 'element';
19
29
  export interface QuickEditSelection {
20
30
  matched: true;
31
+ /** Absent on a component target from an older bridge. */
32
+ kind?: QuickEditTargetKind;
21
33
  component: string;
22
34
  label: string;
23
35
  schema: Record<string, QuickEditField>;
24
36
  values: Record<string, QuickEditValue>;
25
37
  presentProps?: Record<string, boolean>;
38
+ tag?: string;
39
+ ownerLabel?: string;
40
+ classAttr?: string | null;
41
+ classEditable?: boolean;
42
+ hasText?: boolean;
43
+ /** Computed `display`, used to gate flex-only groups. */
44
+ display?: string;
45
+ /** Effective cascade values per group id, for display only. */
46
+ computed?: Record<string, string>;
47
+ /** How many rendered elements share this source location (see the scope hint). */
48
+ instances?: number;
26
49
  rect: {
27
50
  x: number;
28
51
  y: number;
@@ -51,6 +74,12 @@ export interface QuickEditApplyResponse {
51
74
  escalated: QuickEditApplyResult[];
52
75
  results: QuickEditApplyResult[];
53
76
  preview: boolean;
77
+ checkpoint?: {
78
+ id: string;
79
+ status: string;
80
+ contextStatus: string;
81
+ } | null;
82
+ checkpointError?: string | null;
54
83
  }
55
84
  export interface QuickEditHistoryItem {
56
85
  component: string;
@@ -65,6 +94,35 @@ export interface QuickEditHistoryItem {
65
94
  export declare function wrapQuickEditPayload(item: QuickEditHistoryItem): string;
66
95
  export declare function parseQuickEditMessage(text: string): QuickEditHistoryItem | null;
67
96
  export declare function quickEditValueError(field: QuickEditField, value: unknown): string | null;
97
+ export declare const QUICK_EDIT_STYLE_PREFIX = "style:";
98
+ export declare function quickEditStyleGroupId(prop: string): QuickEditClassGroupId | null;
99
+ export declare function isQuickEditStyleProp(prop: string): boolean;
100
+ /**
101
+ * Schema + current values for the style groups a target exposes. Values are read
102
+ * from the element's own class list, so the sidebar shows what the element is
103
+ * actually styled with — the thing an edit will replace.
104
+ */
105
+ export declare function quickEditStyleFields(selection: QuickEditSelection): {
106
+ schema: Record<string, QuickEditField>;
107
+ values: Record<string, QuickEditValue>;
108
+ };
109
+ /** Collapse every style pseudo-field back into one class string. */
110
+ export declare function quickEditClassFromStyles(baseClassAttr: string | null | undefined, values: Record<string, QuickEditValue>): string;
111
+ /**
112
+ * Which entry of the candidate path to open by default.
113
+ *
114
+ * Not simply the innermost: a card is routinely a stack of positioning wrappers
115
+ * (`absolute inset-0`) with identical bounds, and the topmost one carries no class
116
+ * this tool can edit. Defaulting to it opens a panel whose every row reads
117
+ * "Default" while the styled layer and the enclosing component sit unreachable
118
+ * one level out. So prefer the innermost entry that has something actually set,
119
+ * and let the path UI reach the rest.
120
+ */
121
+ export declare function quickEditPreferredTargetIndex(targets: QuickEditSelection[]): number;
122
+ /** Short path label for the candidate breadcrumb, e.g. `<p>` or `Order method tile`. */
123
+ export declare function quickEditTargetPathLabel(target: QuickEditSelection): string;
124
+ /** Human-readable scope warning: an edit here changes every instance. */
125
+ export declare function quickEditScopeHint(selection: QuickEditSelection): string | null;
68
126
  export declare function quickEditShortFile(path: string): string;
69
127
  export declare function buildQuickEditFallbackPrompt(selection: QuickEditSelection, edits: Array<{
70
128
  prop: string;
@@ -0,0 +1,92 @@
1
+ export type QuickEditClassGroupId = 'fontSize' | 'fontWeight' | 'fontFamily' | 'textColor' | 'textAlign' | 'lineHeight' | 'letterSpacing' | 'textTransform' | 'fontStyle' | 'textDecoration' | 'backgroundColor' | 'borderRadius' | 'borderWidth' | 'borderColor' | 'borderStyle' | 'boxShadow' | 'opacity' | 'gap' | 'justifyContent' | 'alignItems';
2
+ export type QuickEditBoxGroupId = 'padding' | 'margin';
3
+ export type QuickEditClassSection = 'typography' | 'box' | 'layout';
4
+ /** `flex` groups are offered only when the element is a flex/grid container. */
5
+ export type QuickEditClassApplies = 'always' | 'flex';
6
+ export type QuickEditBoxSide = 'top' | 'right' | 'bottom' | 'left';
7
+ /**
8
+ * Stands for a group step that is Tailwind's *bare* utility (`rounded`, `border`,
9
+ * `shadow`). Without a sentinel it would encode as an empty string, which the
10
+ * sidebar already uses for "unset / inherit from the cascade".
11
+ */
12
+ export declare const QUICK_EDIT_BARE_VALUE = "__bare__";
13
+ export interface QuickEditClassOption {
14
+ value: string;
15
+ label: string;
16
+ }
17
+ export interface QuickEditClassGroup {
18
+ id: QuickEditClassGroupId;
19
+ label: string;
20
+ /** Utility prefix, `''` for bare utilities such as `uppercase`. */
21
+ prefix: string;
22
+ options: QuickEditClassOption[];
23
+ arbitraryHint?: string;
24
+ section: QuickEditClassSection;
25
+ applies: QuickEditClassApplies;
26
+ }
27
+ export interface QuickEditBoxGroup {
28
+ id: QuickEditBoxGroupId;
29
+ label: string;
30
+ prefix: 'p' | 'm';
31
+ options: QuickEditClassOption[];
32
+ section: QuickEditClassSection;
33
+ }
34
+ export declare const QUICK_EDIT_CLASS_GROUPS: QuickEditClassGroup[];
35
+ export declare const QUICK_EDIT_BOX_GROUPS: QuickEditBoxGroup[];
36
+ export declare function quickEditClassGroup(id: QuickEditClassGroupId): QuickEditClassGroup;
37
+ export declare function quickEditBoxGroup(id: QuickEditBoxGroupId): QuickEditBoxGroup;
38
+ /** The class token a group + value pair writes. */
39
+ export declare function quickEditClassToken(group: QuickEditClassGroup, value: string): string;
40
+ /**
41
+ * Which single-slot group a class token belongs to, or `null`.
42
+ *
43
+ * Variant-prefixed (`sm:text-lg`, `active:scale-95`) and `!important` tokens are
44
+ * deliberately unclaimed: Quick Edit edits the base state only, so a responsive
45
+ * or state override must survive untouched.
46
+ */
47
+ export declare function classifyQuickEditClass(token: string): QuickEditClassGroupId | null;
48
+ export interface QuickEditBoxToken {
49
+ group: QuickEditBoxGroupId;
50
+ sides: QuickEditBoxSide[];
51
+ value: string;
52
+ precedence: number;
53
+ }
54
+ /** Which box group (and which sides) a spacing token drives, or `null`. */
55
+ export declare function classifyQuickEditBoxClass(token: string): QuickEditBoxToken | null;
56
+ /** `T|R|B|L`; an empty segment means that side is not set by any class. */
57
+ export declare function encodeQuickEditBox(sides: Partial<Record<QuickEditBoxSide, string>>): string;
58
+ export declare function decodeQuickEditBox(value: string): Record<QuickEditBoxSide, string>;
59
+ export declare function splitClassAttr(classAttr: string | null | undefined): string[];
60
+ export interface QuickEditClassState {
61
+ /** Group value present on the element (`lg`, `brand-primary/80`, `[15px]`), or null. */
62
+ value: string | null;
63
+ /** True when the value is an arbitrary/modified value with no matching option. */
64
+ custom: boolean;
65
+ }
66
+ /**
67
+ * Current value per single-slot group, read from the element's class list. This is
68
+ * what makes the sidebar truthful: it reports what the element is actually styled
69
+ * with, which is exactly the thing an edit will replace.
70
+ */
71
+ export declare function parseQuickEditClasses(classAttr: string | null | undefined): Partial<Record<QuickEditClassGroupId, QuickEditClassState>>;
72
+ /** Resolve a box group's four sides through Tailwind's all → axis → side cascade. */
73
+ export declare function parseQuickEditBox(classAttr: string | null | undefined, id: QuickEditBoxGroupId): {
74
+ value: string;
75
+ custom: boolean;
76
+ };
77
+ /**
78
+ * Re-emit a box group as the **minimal** token set: `p-4` when all four sides
79
+ * agree, `px-3 py-2` when the axes agree, per-side otherwise. A side left empty
80
+ * emits nothing, so "unset" stays unset rather than being forced to zero.
81
+ */
82
+ export declare function applyQuickEditBox(classAttr: string | null | undefined, id: QuickEditBoxGroupId, encoded: string): string;
83
+ /**
84
+ * Replace a single-slot group's class, preserving order and every unrelated
85
+ * token. An empty `value` removes the group (falls back to the cascade).
86
+ *
87
+ * The new token is appended rather than spliced in place so the result stays
88
+ * stable: a designer flipping between two values does not shuffle the class list.
89
+ */
90
+ export declare function applyQuickEditClass(classAttr: string | null | undefined, id: QuickEditClassGroupId, value: string): string;
91
+ /** Single-slot groups offerable for a target, given its computed display mode. */
92
+ export declare function quickEditClassGroupsFor(display: string | undefined): QuickEditClassGroup[];
@@ -66,6 +66,10 @@ export interface ChatMessage {
66
66
  export type ConnectionStatus = 'idle' | 'starting' | 'ready' | 'error';
67
67
  export type ProjectProvisioningStatus = 'not_started' | 'provisioning' | 'ready' | 'failed';
68
68
  export type ArchiveCodeAction = 'save' | 'discard';
69
+ export type CheckpointTrigger = 'manual' | 'turn_completed' | 'quick_edit' | 'interval' | 'archive' | 'pre_restore' | 'pre_discard' | 'turn_revert' | 'turn_unrevert' | 'restore' | 'release';
70
+ export type CheckpointStatus = 'capturing' | 'local_only' | 'pushed_verified' | 'failed';
71
+ export type CheckpointContextStatus = 'pending' | 'snapshotted' | 'failed' | 'unavailable';
72
+ export type WorkspaceSyncState = 'unavailable' | 'diverged' | 'behind' | 'uncommitted' | 'unpushed' | 'saving' | 'save_failed' | 'synced' | 'unknown';
69
73
  export interface ProjectSummary {
70
74
  businessId: string;
71
75
  businessSlug: string | null;
@@ -94,6 +98,13 @@ export interface AgentSessionSummary {
94
98
  archived_at: string | null;
95
99
  last_event_chunk: number;
96
100
  last_snapshot_at: string | null;
101
+ base_commit_sha: string | null;
102
+ last_checkpoint_id: string | null;
103
+ last_durable_commit_sha: string | null;
104
+ last_pushed_at: string | null;
105
+ dirty_since: string | null;
106
+ checkpoint_status: CheckpointStatus | null;
107
+ checkpoint_error: string | null;
97
108
  attention_action?: string | null;
98
109
  attention_error?: string | null;
99
110
  release_count: number;
@@ -114,10 +125,47 @@ export interface SessionChangesSummary {
114
125
  commitsBehindOrigin: number;
115
126
  headSha: string | null;
116
127
  originSha: string | null;
128
+ syncState: WorkspaceSyncState;
129
+ availability: 'available' | 'unavailable';
130
+ lastCheckpointId: string | null;
131
+ lastDurableCommitSha: string | null;
132
+ lastPushedAt: string | null;
133
+ dirtySince: string | null;
134
+ checkpointStatus: CheckpointStatus | null;
135
+ checkpointError: string | null;
136
+ lastSnapshotAt: string | null;
137
+ latestCheckpoint: SessionCheckpoint | null;
138
+ }
139
+ export interface SessionCheckpoint {
140
+ id: string;
141
+ business_id: string;
142
+ session_id: string;
143
+ sequence: number;
144
+ trigger: CheckpointTrigger;
145
+ status: CheckpointStatus;
146
+ context_status: CheckpointContextStatus;
147
+ base_sha: string | null;
148
+ commit_sha: string | null;
149
+ verified_remote_sha: string | null;
150
+ raw_opencode_message_id: string | null;
151
+ opencode_snapshot_key: string | null;
152
+ workspace_backup_key: string | null;
153
+ file_count: number;
154
+ additions: number;
155
+ deletions: number;
156
+ summary: string | null;
157
+ error_stage: string | null;
158
+ error_message: string | null;
159
+ created_at: string;
160
+ committed_at: string | null;
161
+ pushed_at: string | null;
162
+ context_snapshotted_at: string | null;
163
+ pinned: number;
117
164
  }
118
165
  export interface ReleaseSummary {
119
166
  id: string;
120
167
  source_commit_sha: string;
168
+ checkpoint_id: string | null;
121
169
  created_from_session_id: string | null;
122
170
  session_title: string | null;
123
171
  status: 'draft' | 'preview' | 'published' | 'rolled_back';
@@ -12,6 +12,10 @@ export declare function useChat(): {
12
12
  businessId: string | null;
13
13
  readOnly: boolean;
14
14
  disconnected: boolean;
15
+ checkpointRevision: number;
16
+ checkpointError: string | null;
17
+ checkpointSaving: boolean;
18
+ canUnrevert: boolean;
15
19
  messagesOrder: string[];
16
20
  messagesByKey: Record<string, ChatMessage>;
17
21
  queuedMessages: {
@@ -148,6 +152,9 @@ export declare function useChat(): {
148
152
  suspend: (message?: string) => void;
149
153
  sendMessage: (text: string, attachments?: OutgoingAttachment[]) => boolean;
150
154
  abort: () => Promise<void>;
155
+ revertTurn: (rawOpencodeMessageId: string) => Promise<boolean>;
156
+ unrevertTurn: () => Promise<boolean>;
157
+ reportCheckpointResult: (error?: string | null) => void;
151
158
  restartPreviewServer: () => Promise<boolean>;
152
159
  };
153
160
  export type ChatStore = ReturnType<typeof useChat>;
@@ -1,4 +1,4 @@
1
- import type { ArchiveCodeAction, ProjectSummary, ReleaseSummary, SessionChangesSummary } from './types';
1
+ import type { ArchiveCodeAction, CheckpointTrigger, ProjectSummary, ReleaseSummary, SessionCheckpoint, SessionChangesSummary } from './types';
2
2
  export declare function useProject(): {
3
3
  businessId: string;
4
4
  project: {
@@ -29,6 +29,13 @@ export declare function useProject(): {
29
29
  archived_at: string | null;
30
30
  last_event_chunk: number;
31
31
  last_snapshot_at: string | null;
32
+ base_commit_sha: string | null;
33
+ last_checkpoint_id: string | null;
34
+ last_durable_commit_sha: string | null;
35
+ last_pushed_at: string | null;
36
+ dirty_since: string | null;
37
+ checkpoint_status: import("./types").CheckpointStatus | null;
38
+ checkpoint_error: string | null;
32
39
  attention_action?: string | null | undefined;
33
40
  attention_error?: string | null | undefined;
34
41
  release_count: number;
@@ -39,6 +46,7 @@ export declare function useProject(): {
39
46
  releases: {
40
47
  id: string;
41
48
  source_commit_sha: string;
49
+ checkpoint_id: string | null;
42
50
  created_from_session_id: string | null;
43
51
  session_title: string | null;
44
52
  status: "draft" | "preview" | "published" | "rolled_back";
@@ -52,6 +60,82 @@ export declare function useProject(): {
52
60
  build_created_at: string | null;
53
61
  build_completed_at: string | null;
54
62
  }[];
63
+ workspaceState: {
64
+ businessId: string;
65
+ sessionId: string;
66
+ workspaceExists: boolean;
67
+ dirty: boolean;
68
+ hasUncommittedChanges: boolean;
69
+ hasUnpushedCommits: boolean;
70
+ headDiffersFromOrigin: boolean;
71
+ statusCount: number;
72
+ commitsAheadOrigin: number;
73
+ commitsBehindOrigin: number;
74
+ headSha: string | null;
75
+ originSha: string | null;
76
+ syncState: import("./types").WorkspaceSyncState;
77
+ availability: "available" | "unavailable";
78
+ lastCheckpointId: string | null;
79
+ lastDurableCommitSha: string | null;
80
+ lastPushedAt: string | null;
81
+ dirtySince: string | null;
82
+ checkpointStatus: import("./types").CheckpointStatus | null;
83
+ checkpointError: string | null;
84
+ lastSnapshotAt: string | null;
85
+ latestCheckpoint: {
86
+ id: string;
87
+ business_id: string;
88
+ session_id: string;
89
+ sequence: number;
90
+ trigger: CheckpointTrigger;
91
+ status: import("./types").CheckpointStatus;
92
+ context_status: import("./types").CheckpointContextStatus;
93
+ base_sha: string | null;
94
+ commit_sha: string | null;
95
+ verified_remote_sha: string | null;
96
+ raw_opencode_message_id: string | null;
97
+ opencode_snapshot_key: string | null;
98
+ workspace_backup_key: string | null;
99
+ file_count: number;
100
+ additions: number;
101
+ deletions: number;
102
+ summary: string | null;
103
+ error_stage: string | null;
104
+ error_message: string | null;
105
+ created_at: string;
106
+ committed_at: string | null;
107
+ pushed_at: string | null;
108
+ context_snapshotted_at: string | null;
109
+ pinned: number;
110
+ } | null;
111
+ } | null;
112
+ checkpoints: {
113
+ id: string;
114
+ business_id: string;
115
+ session_id: string;
116
+ sequence: number;
117
+ trigger: CheckpointTrigger;
118
+ status: import("./types").CheckpointStatus;
119
+ context_status: import("./types").CheckpointContextStatus;
120
+ base_sha: string | null;
121
+ commit_sha: string | null;
122
+ verified_remote_sha: string | null;
123
+ raw_opencode_message_id: string | null;
124
+ opencode_snapshot_key: string | null;
125
+ workspace_backup_key: string | null;
126
+ file_count: number;
127
+ additions: number;
128
+ deletions: number;
129
+ summary: string | null;
130
+ error_stage: string | null;
131
+ error_message: string | null;
132
+ created_at: string;
133
+ committed_at: string | null;
134
+ pushed_at: string | null;
135
+ context_snapshotted_at: string | null;
136
+ pinned: number;
137
+ }[];
138
+ checkpointBusy: boolean;
55
139
  busy: boolean;
56
140
  statusText: string;
57
141
  activeReleaseId: string | null;
@@ -59,6 +143,7 @@ export declare function useProject(): {
59
143
  latestRelease: {
60
144
  id: string;
61
145
  source_commit_sha: string;
146
+ checkpoint_id: string | null;
62
147
  created_from_session_id: string | null;
63
148
  session_title: string | null;
64
149
  status: "draft" | "preview" | "published" | "rolled_back";
@@ -88,21 +173,40 @@ export declare function useProject(): {
88
173
  sessionId: string;
89
174
  previewUrl: string;
90
175
  }>;
91
- sessionChanges: (sessionId: string) => Promise<SessionChangesSummary>;
176
+ sessionChanges: (sessionId: string, refreshRemote?: boolean) => Promise<SessionChangesSummary>;
177
+ refreshWorkspaceState: (sessionId: string, refreshRemote?: boolean) => Promise<SessionChangesSummary>;
178
+ refreshCheckpoints: (sessionId: string) => Promise<SessionCheckpoint[]>;
179
+ checkpointSession: (sessionId: string, options?: {
180
+ trigger?: CheckpointTrigger;
181
+ idempotencyKey?: string;
182
+ rawOpencodeMessageId?: string;
183
+ summary?: string;
184
+ }) => Promise<{
185
+ checkpoint: SessionCheckpoint;
186
+ sourceCommitSha: string;
187
+ reused: boolean;
188
+ }>;
189
+ restoreCheckpoint: (sessionId: string, checkpointId: string) => Promise<{
190
+ checkpoint: SessionCheckpoint;
191
+ sourceCommitSha: string;
192
+ }>;
92
193
  resumeSession: (sessionId: string) => Promise<{
93
194
  sessionId: string;
94
195
  previewUrl: string;
95
196
  }>;
96
197
  renameSession: (sessionId: string, title: string) => Promise<void>;
97
198
  commitSession: (sessionId: string) => Promise<{
199
+ checkpoint: SessionCheckpoint;
98
200
  sourceCommitSha: string;
201
+ reused: boolean;
99
202
  }>;
100
- createRelease: (sourceCommitSha: string, sessionId?: string) => Promise<{
203
+ createRelease: (checkpointId: string, sessionId?: string) => Promise<{
101
204
  releaseId: string;
102
205
  buildJobId: string;
103
206
  previewUrl: string;
104
207
  }>;
105
208
  publish: (releaseId?: string | null) => Promise<void>;
209
+ rollbackToRelease: (releaseId: string) => Promise<void>;
106
210
  rollbackToV1: () => Promise<void>;
107
211
  };
108
212
  export type ProjectStore = ReturnType<typeof useProject>;