@agent-native/core 0.77.10 → 0.77.12
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/package.json +3 -3
- package/corpus/core/src/cli/create.ts +65 -15
- package/corpus/core/src/cli/sync-builder-starter-manifest.ts +261 -65
- package/corpus/core/src/collab/awareness.ts +12 -9
- package/corpus/core/src/collab/client.ts +4 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +1 -1
- package/corpus/templates/clips/chrome-extension/package.json +1 -1
- package/corpus/templates/clips/desktop/src/app.tsx +35 -19
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +38 -1
- package/corpus/templates/clips/desktop/src/styles.css +35 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +343 -14
- package/corpus/templates/content/actions/list-trashed-content-databases.ts +36 -2
- package/corpus/templates/content/actions/move-document.ts +79 -33
- package/corpus/templates/content/actions/restore-content-database.ts +40 -3
- package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +84 -2
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +177 -49
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +393 -219
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +632 -467
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +114 -14
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +56 -15
- package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +6 -5
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +12 -4
- package/corpus/templates/content/app/global.css +9 -0
- package/corpus/templates/content/app/hooks/use-create-page.ts +36 -7
- package/corpus/templates/content/app/i18n-data.ts +140 -10
- package/corpus/templates/content/changelog/2026-06-25-comment-cards-now-track-their-highlighted-text-while-scrolli.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-comments-now-scroll-with-the-document-and-stay-below-the-pag.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-creating-a-database-from-the-slash-menu-no-longer-leaves-sta.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-sidebar-hover-controls-no-longer-leave-a-lingering-fade-when.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-sidebar-page-actions-are-now-easier-to-see-when-hovering-ina.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-text-selections-in-the-editor-no-longer-show-white-gaps-when.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-the-editor-toolbar-now-has-a-one-click-page-link-copy-button.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-the-editor-toolbar-now-shows-page-breadcrumbs-and-the-latest.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-the-page-command-now-leaves-a-notion-style-page-reference-an.md +6 -0
- package/corpus/templates/content/shared/nfm.ts +16 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +53 -15
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/sync-builder-starter-manifest.d.ts +36 -2
- package/dist/cli/sync-builder-starter-manifest.d.ts.map +1 -1
- package/dist/cli/sync-builder-starter-manifest.js +180 -37
- package/dist/cli/sync-builder-starter-manifest.js.map +1 -1
- package/dist/collab/awareness.d.ts +1 -1
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +12 -8
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +4 -3
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +2 -2
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
export declare const STARTER_APP_NAME = "builder-agent-native-starter";
|
|
2
2
|
export declare const CHAT_TEMPLATE = "chat";
|
|
3
|
+
/** Toolchain files that must track templates/chat or typecheck/build drift. */
|
|
4
|
+
export declare const STARTER_TOOLCHAIN_SYNC_PATHS: readonly ["react-router.config.ts", "vite.config.ts", "tsconfig.json", "ssr-entry.ts", "app/vite-env.d.ts", "app/routes.ts", "server/routes/[...page].get.ts", "server/middleware/auth.ts", "components.json", ".oxfmtrc.json", "netlify.toml"];
|
|
5
|
+
export type StarterToolchainSyncPath = (typeof STARTER_TOOLCHAIN_SYNC_PATHS)[number];
|
|
3
6
|
type PackageJson = Record<string, unknown>;
|
|
7
|
+
export type StandaloneChatSnapshot = {
|
|
8
|
+
cleanup: () => void;
|
|
9
|
+
dir: string;
|
|
10
|
+
packageJson: PackageJson;
|
|
11
|
+
pnpmWorkspaceYaml: string | null;
|
|
12
|
+
toolchainFiles: Map<StarterToolchainSyncPath, string>;
|
|
13
|
+
};
|
|
14
|
+
export declare function listStarterSyncPaths(): string[];
|
|
4
15
|
export declare function findAgentNativeRoot(startDir?: string): string;
|
|
16
|
+
export declare function collectStarterToolchainFiles(canonicalDir: string): Map<StarterToolchainSyncPath, string>;
|
|
17
|
+
export declare function createStandaloneChatSnapshot(repoRoot?: string): StandaloneChatSnapshot;
|
|
5
18
|
export declare function generateStandaloneChatManifest(repoRoot?: string): {
|
|
6
19
|
packageJson: PackageJson;
|
|
7
20
|
pnpmWorkspaceYaml: string | null;
|
|
@@ -9,19 +22,40 @@ export declare function generateStandaloneChatManifest(repoRoot?: string): {
|
|
|
9
22
|
export declare function mergeStarterManifest(starterPackageJson: PackageJson, canonicalPackageJson: PackageJson): PackageJson;
|
|
10
23
|
export declare function workspaceFileSyncChanged(existingWorkspace: string | null, canonicalWorkspace: string | null): boolean;
|
|
11
24
|
export declare function applyWorkspaceFileSync(targetPath: string, canonicalWorkspace: string | null): void;
|
|
25
|
+
export type StarterToolchainSyncChange = {
|
|
26
|
+
relativePath: StarterToolchainSyncPath;
|
|
27
|
+
changed: boolean;
|
|
28
|
+
};
|
|
29
|
+
export declare function diffStarterToolchainFiles(starterDir: string, canonicalFiles: Map<StarterToolchainSyncPath, string>): StarterToolchainSyncChange[];
|
|
30
|
+
export declare function applyStarterToolchainSync(starterDir: string, canonicalFiles: Map<StarterToolchainSyncPath, string>): StarterToolchainSyncChange[];
|
|
12
31
|
export type SyncStarterManifestResult = {
|
|
13
32
|
changed: boolean;
|
|
33
|
+
packageChanged: boolean;
|
|
34
|
+
workspaceChanged: boolean;
|
|
14
35
|
packageJson: PackageJson;
|
|
15
36
|
pnpmWorkspaceYaml: string | null;
|
|
37
|
+
toolchainChanges: StarterToolchainSyncChange[];
|
|
38
|
+
changedToolchainPaths: StarterToolchainSyncPath[];
|
|
16
39
|
};
|
|
17
|
-
export declare function
|
|
40
|
+
export declare function resolveStarterPaths(options: {
|
|
41
|
+
starterDir?: string;
|
|
42
|
+
starterPackageJsonPath?: string;
|
|
43
|
+
starterPnpmWorkspacePath?: string;
|
|
44
|
+
}): {
|
|
45
|
+
starterDir: string;
|
|
18
46
|
starterPackageJsonPath: string;
|
|
47
|
+
starterPnpmWorkspacePath: string;
|
|
48
|
+
};
|
|
49
|
+
export declare function syncStarterManifestFiles(options: {
|
|
50
|
+
starterDir?: string;
|
|
51
|
+
starterPackageJsonPath?: string;
|
|
19
52
|
starterPnpmWorkspacePath?: string;
|
|
20
53
|
repoRoot?: string;
|
|
21
54
|
write?: boolean;
|
|
22
55
|
}): SyncStarterManifestResult;
|
|
23
56
|
export declare function parseSyncStarterManifestArgs(argv: string[]): {
|
|
24
|
-
command: "merge" | "generate";
|
|
57
|
+
command: "merge" | "generate" | "paths";
|
|
58
|
+
starterDir?: string;
|
|
25
59
|
starterPackageJsonPath?: string;
|
|
26
60
|
starterPnpmWorkspacePath?: string;
|
|
27
61
|
write: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-builder-starter-manifest.d.ts","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB,iCAAiC,CAAC;AAC/D,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,wBAAgB,mBAAmB,CAAC,QAAQ,SAAgB,GAAG,MAAM,CAmBpE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,
|
|
1
|
+
{"version":3,"file":"sync-builder-starter-manifest.d.ts","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,30 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { _postProcessStandalone } from "./create.js";
|
|
6
6
|
export const STARTER_APP_NAME = "builder-agent-native-starter";
|
|
7
7
|
export const CHAT_TEMPLATE = "chat";
|
|
8
|
+
/** Toolchain files that must track templates/chat or typecheck/build drift. */
|
|
9
|
+
export const STARTER_TOOLCHAIN_SYNC_PATHS = [
|
|
10
|
+
"react-router.config.ts",
|
|
11
|
+
"vite.config.ts",
|
|
12
|
+
"tsconfig.json",
|
|
13
|
+
"ssr-entry.ts",
|
|
14
|
+
"app/vite-env.d.ts",
|
|
15
|
+
"app/routes.ts",
|
|
16
|
+
"server/routes/[...page].get.ts",
|
|
17
|
+
// server/plugins/* are intentionally excluded: starter keeps its own
|
|
18
|
+
// systemPrompt and auth marketing copy; post-process only rewrites appId/title.
|
|
19
|
+
"server/middleware/auth.ts",
|
|
20
|
+
"components.json",
|
|
21
|
+
".oxfmtrc.json",
|
|
22
|
+
"netlify.toml",
|
|
23
|
+
];
|
|
24
|
+
export function listStarterSyncPaths() {
|
|
25
|
+
return [
|
|
26
|
+
"package.json",
|
|
27
|
+
"pnpm-lock.yaml",
|
|
28
|
+
"pnpm-workspace.yaml",
|
|
29
|
+
...STARTER_TOOLCHAIN_SYNC_PATHS,
|
|
30
|
+
];
|
|
31
|
+
}
|
|
8
32
|
export function findAgentNativeRoot(startDir = process.cwd()) {
|
|
9
33
|
let dir = path.resolve(startDir);
|
|
10
34
|
for (let i = 0; i < 12; i++) {
|
|
@@ -19,22 +43,47 @@ export function findAgentNativeRoot(startDir = process.cwd()) {
|
|
|
19
43
|
}
|
|
20
44
|
throw new Error("Could not find agent-native repo root (expected templates/chat/package.json).");
|
|
21
45
|
}
|
|
22
|
-
export function
|
|
46
|
+
export function collectStarterToolchainFiles(canonicalDir) {
|
|
47
|
+
const files = new Map();
|
|
48
|
+
for (const relativePath of STARTER_TOOLCHAIN_SYNC_PATHS) {
|
|
49
|
+
const absolutePath = path.join(canonicalDir, relativePath);
|
|
50
|
+
if (!fs.existsSync(absolutePath))
|
|
51
|
+
continue;
|
|
52
|
+
files.set(relativePath, fs.readFileSync(absolutePath, "utf-8"));
|
|
53
|
+
}
|
|
54
|
+
return files;
|
|
55
|
+
}
|
|
56
|
+
export function createStandaloneChatSnapshot(repoRoot) {
|
|
23
57
|
const root = repoRoot ?? findAgentNativeRoot();
|
|
24
58
|
const chatTemplateDir = path.join(root, "templates", CHAT_TEMPLATE);
|
|
25
59
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "an-builder-starter-sync-"));
|
|
60
|
+
fs.cpSync(chatTemplateDir, tempDir, { recursive: true });
|
|
61
|
+
_postProcessStandalone(STARTER_APP_NAME, tempDir, CHAT_TEMPLATE);
|
|
62
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(tempDir, "package.json"), "utf-8"));
|
|
63
|
+
const workspacePath = path.join(tempDir, "pnpm-workspace.yaml");
|
|
64
|
+
const pnpmWorkspaceYaml = fs.existsSync(workspacePath)
|
|
65
|
+
? fs.readFileSync(workspacePath, "utf-8")
|
|
66
|
+
: null;
|
|
67
|
+
return {
|
|
68
|
+
cleanup: () => {
|
|
69
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
70
|
+
},
|
|
71
|
+
dir: tempDir,
|
|
72
|
+
packageJson,
|
|
73
|
+
pnpmWorkspaceYaml,
|
|
74
|
+
toolchainFiles: collectStarterToolchainFiles(tempDir),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function generateStandaloneChatManifest(repoRoot) {
|
|
78
|
+
const snapshot = createStandaloneChatSnapshot(repoRoot);
|
|
26
79
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const pnpmWorkspaceYaml = fs.existsSync(workspacePath)
|
|
32
|
-
? fs.readFileSync(workspacePath, "utf-8")
|
|
33
|
-
: null;
|
|
34
|
-
return { packageJson, pnpmWorkspaceYaml };
|
|
80
|
+
return {
|
|
81
|
+
packageJson: snapshot.packageJson,
|
|
82
|
+
pnpmWorkspaceYaml: snapshot.pnpmWorkspaceYaml,
|
|
83
|
+
};
|
|
35
84
|
}
|
|
36
85
|
finally {
|
|
37
|
-
|
|
86
|
+
snapshot.cleanup();
|
|
38
87
|
}
|
|
39
88
|
}
|
|
40
89
|
function mergePackageJsonRecords(canonical, starter, starterPinnedKeys = []) {
|
|
@@ -90,35 +139,111 @@ export function applyWorkspaceFileSync(targetPath, canonicalWorkspace) {
|
|
|
90
139
|
function stableJson(value) {
|
|
91
140
|
return `${JSON.stringify(value, null, 2)}\n`;
|
|
92
141
|
}
|
|
93
|
-
export function
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
142
|
+
export function diffStarterToolchainFiles(starterDir, canonicalFiles) {
|
|
143
|
+
return STARTER_TOOLCHAIN_SYNC_PATHS.map((relativePath) => {
|
|
144
|
+
const canonicalContent = canonicalFiles.get(relativePath) ?? null;
|
|
145
|
+
const targetPath = path.join(starterDir, relativePath);
|
|
146
|
+
const existingContent = fs.existsSync(targetPath)
|
|
147
|
+
? fs.readFileSync(targetPath, "utf-8")
|
|
148
|
+
: null;
|
|
149
|
+
return {
|
|
150
|
+
relativePath,
|
|
151
|
+
changed: existingContent !== canonicalContent,
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
export function applyStarterToolchainSync(starterDir, canonicalFiles) {
|
|
156
|
+
const changes = [];
|
|
157
|
+
for (const relativePath of STARTER_TOOLCHAIN_SYNC_PATHS) {
|
|
158
|
+
const canonicalContent = canonicalFiles.get(relativePath) ?? null;
|
|
159
|
+
const targetPath = path.join(starterDir, relativePath);
|
|
160
|
+
const existingContent = fs.existsSync(targetPath)
|
|
161
|
+
? fs.readFileSync(targetPath, "utf-8")
|
|
162
|
+
: null;
|
|
163
|
+
const changed = existingContent !== canonicalContent;
|
|
164
|
+
if (changed) {
|
|
165
|
+
if (canonicalContent === null) {
|
|
166
|
+
if (fs.existsSync(targetPath)) {
|
|
167
|
+
fs.unlinkSync(targetPath);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
172
|
+
fs.writeFileSync(targetPath, canonicalContent);
|
|
173
|
+
}
|
|
111
174
|
}
|
|
175
|
+
changes.push({ relativePath, changed });
|
|
112
176
|
}
|
|
177
|
+
return changes;
|
|
178
|
+
}
|
|
179
|
+
export function resolveStarterPaths(options) {
|
|
180
|
+
if (options.starterDir) {
|
|
181
|
+
return {
|
|
182
|
+
starterDir: path.resolve(options.starterDir),
|
|
183
|
+
starterPackageJsonPath: path.join(path.resolve(options.starterDir), "package.json"),
|
|
184
|
+
starterPnpmWorkspacePath: path.join(path.resolve(options.starterDir), "pnpm-workspace.yaml"),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (!options.starterPackageJsonPath) {
|
|
188
|
+
throw new Error("Provide --starter-dir or --starter-package-json.");
|
|
189
|
+
}
|
|
190
|
+
const starterPackageJsonPath = path.resolve(options.starterPackageJsonPath);
|
|
113
191
|
return {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
192
|
+
starterDir: path.dirname(starterPackageJsonPath),
|
|
193
|
+
starterPackageJsonPath,
|
|
194
|
+
starterPnpmWorkspacePath: options.starterPnpmWorkspacePath ??
|
|
195
|
+
path.join(path.dirname(starterPackageJsonPath), "pnpm-workspace.yaml"),
|
|
117
196
|
};
|
|
118
197
|
}
|
|
198
|
+
export function syncStarterManifestFiles(options) {
|
|
199
|
+
const { starterDir, starterPackageJsonPath, starterPnpmWorkspacePath } = resolveStarterPaths(options);
|
|
200
|
+
const snapshot = createStandaloneChatSnapshot(options.repoRoot);
|
|
201
|
+
try {
|
|
202
|
+
const starterPackageJson = JSON.parse(fs.readFileSync(starterPackageJsonPath, "utf-8"));
|
|
203
|
+
const mergedPackageJson = mergeStarterManifest(starterPackageJson, snapshot.packageJson);
|
|
204
|
+
const existingWorkspace = fs.existsSync(starterPnpmWorkspacePath)
|
|
205
|
+
? fs.readFileSync(starterPnpmWorkspacePath, "utf-8")
|
|
206
|
+
: null;
|
|
207
|
+
const workspaceChanged = workspaceFileSyncChanged(existingWorkspace, snapshot.pnpmWorkspaceYaml);
|
|
208
|
+
const packageChanged = stableJson(starterPackageJson) !== stableJson(mergedPackageJson);
|
|
209
|
+
const toolchainChanges = diffStarterToolchainFiles(starterDir, snapshot.toolchainFiles);
|
|
210
|
+
const changedToolchainPaths = toolchainChanges
|
|
211
|
+
.filter((change) => change.changed)
|
|
212
|
+
.map((change) => change.relativePath);
|
|
213
|
+
const changed = packageChanged || workspaceChanged || changedToolchainPaths.length > 0;
|
|
214
|
+
if (options.write && changed) {
|
|
215
|
+
if (packageChanged) {
|
|
216
|
+
fs.writeFileSync(starterPackageJsonPath, stableJson(mergedPackageJson));
|
|
217
|
+
}
|
|
218
|
+
if (workspaceChanged) {
|
|
219
|
+
applyWorkspaceFileSync(starterPnpmWorkspacePath, snapshot.pnpmWorkspaceYaml);
|
|
220
|
+
}
|
|
221
|
+
if (changedToolchainPaths.length > 0) {
|
|
222
|
+
applyStarterToolchainSync(starterDir, snapshot.toolchainFiles);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
changed,
|
|
227
|
+
packageChanged,
|
|
228
|
+
workspaceChanged,
|
|
229
|
+
packageJson: mergedPackageJson,
|
|
230
|
+
pnpmWorkspaceYaml: snapshot.pnpmWorkspaceYaml,
|
|
231
|
+
toolchainChanges,
|
|
232
|
+
changedToolchainPaths,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
snapshot.cleanup();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
119
239
|
export function parseSyncStarterManifestArgs(argv) {
|
|
120
240
|
const [commandRaw, ...rest] = argv;
|
|
121
|
-
const command = commandRaw === "generate"
|
|
241
|
+
const command = commandRaw === "generate"
|
|
242
|
+
? "generate"
|
|
243
|
+
: commandRaw === "paths"
|
|
244
|
+
? "paths"
|
|
245
|
+
: "merge";
|
|
246
|
+
let starterDir;
|
|
122
247
|
let starterPackageJsonPath;
|
|
123
248
|
let starterPnpmWorkspacePath;
|
|
124
249
|
let write = false;
|
|
@@ -129,6 +254,10 @@ export function parseSyncStarterManifestArgs(argv) {
|
|
|
129
254
|
write = true;
|
|
130
255
|
continue;
|
|
131
256
|
}
|
|
257
|
+
if (arg === "--starter-dir") {
|
|
258
|
+
starterDir = rest[++i];
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
132
261
|
if (arg === "--starter-package-json") {
|
|
133
262
|
starterPackageJsonPath = rest[++i];
|
|
134
263
|
continue;
|
|
@@ -143,11 +272,12 @@ export function parseSyncStarterManifestArgs(argv) {
|
|
|
143
272
|
}
|
|
144
273
|
throw new Error(`Unknown argument: ${arg}`);
|
|
145
274
|
}
|
|
146
|
-
if (command === "merge" && !starterPackageJsonPath) {
|
|
147
|
-
throw new Error("merge requires --starter-package-json <path> [--starter-pnpm-workspace <path>] [--write] [--repo-root <path>]");
|
|
275
|
+
if (command === "merge" && !starterDir && !starterPackageJsonPath) {
|
|
276
|
+
throw new Error("merge requires --starter-dir <path> or --starter-package-json <path> [--starter-pnpm-workspace <path>] [--write] [--repo-root <path>]");
|
|
148
277
|
}
|
|
149
278
|
return {
|
|
150
279
|
command,
|
|
280
|
+
starterDir,
|
|
151
281
|
starterPackageJsonPath,
|
|
152
282
|
starterPnpmWorkspacePath,
|
|
153
283
|
write,
|
|
@@ -165,19 +295,32 @@ export function runSyncStarterManifestCli(argv) {
|
|
|
165
295
|
}
|
|
166
296
|
return 0;
|
|
167
297
|
}
|
|
298
|
+
if (args.command === "paths") {
|
|
299
|
+
for (const syncPath of listStarterSyncPaths()) {
|
|
300
|
+
process.stdout.write(`${syncPath}\n`);
|
|
301
|
+
}
|
|
302
|
+
return 0;
|
|
303
|
+
}
|
|
168
304
|
const result = syncStarterManifestFiles({
|
|
305
|
+
starterDir: args.starterDir,
|
|
169
306
|
starterPackageJsonPath: args.starterPackageJsonPath,
|
|
170
307
|
starterPnpmWorkspacePath: args.starterPnpmWorkspacePath,
|
|
171
308
|
repoRoot: args.repoRoot,
|
|
172
309
|
write: args.write,
|
|
173
310
|
});
|
|
174
311
|
if (result.changed) {
|
|
312
|
+
const updatedPaths = [
|
|
313
|
+
...(result.packageChanged ? ["package.json"] : []),
|
|
314
|
+
...(result.workspaceChanged ? ["pnpm-workspace.yaml"] : []),
|
|
315
|
+
...result.changedToolchainPaths,
|
|
316
|
+
];
|
|
317
|
+
const summary = updatedPaths.length ? ` (${updatedPaths.join(", ")})` : "";
|
|
175
318
|
console.log(args.write
|
|
176
|
-
?
|
|
177
|
-
:
|
|
319
|
+
? `Updated builder-agent-native-starter from templates/chat${summary}.`
|
|
320
|
+
: `builder-agent-native-starter is out of date with templates/chat${summary}.`);
|
|
178
321
|
return args.write ? 0 : 1;
|
|
179
322
|
}
|
|
180
|
-
console.log("builder-agent-native-starter
|
|
323
|
+
console.log("builder-agent-native-starter already matches templates/chat.");
|
|
181
324
|
return 0;
|
|
182
325
|
}
|
|
183
326
|
const isDirectRun = process.argv[1] &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-builder-starter-manifest.js","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { _postProcessStandalone } from \"./create.js\";\n\nexport const STARTER_APP_NAME = \"builder-agent-native-starter\";\nexport const CHAT_TEMPLATE = \"chat\";\n\ntype PackageJson = Record<string, unknown>;\n\nexport function findAgentNativeRoot(startDir = process.cwd()): string {\n let dir = path.resolve(startDir);\n for (let i = 0; i < 12; i++) {\n const chatPackageJson = path.join(\n dir,\n \"templates\",\n CHAT_TEMPLATE,\n \"package.json\",\n );\n if (fs.existsSync(chatPackageJson)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"Could not find agent-native repo root (expected templates/chat/package.json).\",\n );\n}\n\nexport function generateStandaloneChatManifest(repoRoot?: string): {\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n} {\n const root = repoRoot ?? findAgentNativeRoot();\n const chatTemplateDir = path.join(root, \"templates\", CHAT_TEMPLATE);\n const tempDir = fs.mkdtempSync(\n path.join(os.tmpdir(), \"an-builder-starter-sync-\"),\n );\n\n try {\n fs.cpSync(chatTemplateDir, tempDir, { recursive: true });\n _postProcessStandalone(STARTER_APP_NAME, tempDir, CHAT_TEMPLATE);\n\n const packageJson = JSON.parse(\n fs.readFileSync(path.join(tempDir, \"package.json\"), \"utf-8\"),\n ) as PackageJson;\n\n const workspacePath = path.join(tempDir, \"pnpm-workspace.yaml\");\n const pnpmWorkspaceYaml = fs.existsSync(workspacePath)\n ? fs.readFileSync(workspacePath, \"utf-8\")\n : null;\n\n return { packageJson, pnpmWorkspaceYaml };\n } finally {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\nfunction mergePackageJsonRecords(\n canonical: Record<string, string> | undefined,\n starter: Record<string, string> | undefined,\n starterPinnedKeys: string[] = [],\n): Record<string, string> {\n const merged = { ...(canonical ?? {}) };\n for (const [key, value] of Object.entries(starter ?? {})) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n for (const key of starterPinnedKeys) {\n const pinned = starter?.[key];\n if (pinned) {\n merged[key] = pinned;\n }\n }\n return merged;\n}\n\nexport function mergeStarterManifest(\n starterPackageJson: PackageJson,\n canonicalPackageJson: PackageJson,\n): PackageJson {\n const merged = structuredClone(canonicalPackageJson) as PackageJson;\n\n merged.name = starterPackageJson.name ?? STARTER_APP_NAME;\n if (typeof starterPackageJson.displayName === \"string\") {\n merged.displayName = starterPackageJson.displayName;\n }\n if (typeof starterPackageJson.description === \"string\") {\n merged.description = starterPackageJson.description;\n }\n if (starterPackageJson.private !== undefined) {\n merged.private = starterPackageJson.private;\n }\n if (typeof starterPackageJson.packageManager === \"string\") {\n merged.packageManager = starterPackageJson.packageManager;\n }\n\n merged.dependencies = mergePackageJsonRecords(\n canonicalPackageJson.dependencies as Record<string, string> | undefined,\n starterPackageJson.dependencies as Record<string, string> | undefined,\n [\"@agent-native/core\"],\n );\n merged.devDependencies = mergePackageJsonRecords(\n canonicalPackageJson.devDependencies as Record<string, string> | undefined,\n starterPackageJson.devDependencies as Record<string, string> | undefined,\n );\n merged.scripts = mergePackageJsonRecords(\n canonicalPackageJson.scripts as Record<string, string> | undefined,\n starterPackageJson.scripts as Record<string, string> | undefined,\n );\n\n return merged;\n}\n\nexport function workspaceFileSyncChanged(\n existingWorkspace: string | null,\n canonicalWorkspace: string | null,\n): boolean {\n if (canonicalWorkspace === null) {\n return existingWorkspace !== null;\n }\n return existingWorkspace !== canonicalWorkspace;\n}\n\nexport function applyWorkspaceFileSync(\n targetPath: string,\n canonicalWorkspace: string | null,\n): void {\n if (canonicalWorkspace === null) {\n if (fs.existsSync(targetPath)) {\n fs.unlinkSync(targetPath);\n }\n return;\n }\n fs.writeFileSync(targetPath, canonicalWorkspace);\n}\n\nfunction stableJson(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nexport type SyncStarterManifestResult = {\n changed: boolean;\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n};\n\nexport function syncStarterManifestFiles(options: {\n starterPackageJsonPath: string;\n starterPnpmWorkspacePath?: string;\n repoRoot?: string;\n write?: boolean;\n}): SyncStarterManifestResult {\n const { packageJson: canonical, pnpmWorkspaceYaml } =\n generateStandaloneChatManifest(options.repoRoot);\n\n const starterPackageJson = JSON.parse(\n fs.readFileSync(options.starterPackageJsonPath, \"utf-8\"),\n ) as PackageJson;\n const mergedPackageJson = mergeStarterManifest(starterPackageJson, canonical);\n\n let workspaceChanged = false;\n const existingWorkspace =\n options.starterPnpmWorkspacePath &&\n fs.existsSync(options.starterPnpmWorkspacePath)\n ? fs.readFileSync(options.starterPnpmWorkspacePath, \"utf-8\")\n : null;\n\n workspaceChanged = workspaceFileSyncChanged(\n existingWorkspace,\n pnpmWorkspaceYaml,\n );\n\n const packageChanged =\n stableJson(starterPackageJson) !== stableJson(mergedPackageJson);\n const changed = packageChanged || workspaceChanged;\n\n if (options.write && changed) {\n if (packageChanged) {\n fs.writeFileSync(\n options.starterPackageJsonPath,\n stableJson(mergedPackageJson),\n );\n }\n if (workspaceChanged && options.starterPnpmWorkspacePath) {\n applyWorkspaceFileSync(\n options.starterPnpmWorkspacePath,\n pnpmWorkspaceYaml,\n );\n }\n }\n\n return {\n changed,\n packageJson: mergedPackageJson,\n pnpmWorkspaceYaml,\n };\n}\n\nexport function parseSyncStarterManifestArgs(argv: string[]): {\n command: \"merge\" | \"generate\";\n starterPackageJsonPath?: string;\n starterPnpmWorkspacePath?: string;\n write: boolean;\n repoRoot?: string;\n} {\n const [commandRaw, ...rest] = argv;\n const command = commandRaw === \"generate\" ? \"generate\" : \"merge\";\n let starterPackageJsonPath: string | undefined;\n let starterPnpmWorkspacePath: string | undefined;\n let write = false;\n let repoRoot: string | undefined;\n\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n if (arg === \"--write\") {\n write = true;\n continue;\n }\n if (arg === \"--starter-package-json\") {\n starterPackageJsonPath = rest[++i];\n continue;\n }\n if (arg === \"--starter-pnpm-workspace\") {\n starterPnpmWorkspacePath = rest[++i];\n continue;\n }\n if (arg === \"--repo-root\") {\n repoRoot = rest[++i];\n continue;\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n if (command === \"merge\" && !starterPackageJsonPath) {\n throw new Error(\n \"merge requires --starter-package-json <path> [--starter-pnpm-workspace <path>] [--write] [--repo-root <path>]\",\n );\n }\n\n return {\n command,\n starterPackageJsonPath,\n starterPnpmWorkspacePath,\n write,\n repoRoot,\n };\n}\n\nexport function runSyncStarterManifestCli(argv: string[]): number {\n const args = parseSyncStarterManifestArgs(argv);\n\n if (args.command === \"generate\") {\n const { packageJson, pnpmWorkspaceYaml } = generateStandaloneChatManifest(\n args.repoRoot,\n );\n process.stdout.write(stableJson(packageJson));\n if (pnpmWorkspaceYaml) {\n process.stdout.write(\"\\n--- pnpm-workspace.yaml ---\\n\");\n process.stdout.write(pnpmWorkspaceYaml);\n }\n return 0;\n }\n\n const result = syncStarterManifestFiles({\n starterPackageJsonPath: args.starterPackageJsonPath!,\n starterPnpmWorkspacePath: args.starterPnpmWorkspacePath,\n repoRoot: args.repoRoot,\n write: args.write,\n });\n\n if (result.changed) {\n console.log(\n args.write\n ? \"Updated builder-agent-native-starter manifest from templates/chat.\"\n : \"builder-agent-native-starter manifest is out of date with templates/chat.\",\n );\n return args.write ? 0 : 1;\n }\n\n console.log(\n \"builder-agent-native-starter manifest already matches templates/chat.\",\n );\n return 0;\n}\n\nconst isDirectRun =\n process.argv[1] &&\n path.resolve(process.argv[1]) ===\n path.resolve(fileURLToPath(import.meta.url));\n\nif (isDirectRun) {\n const exitCode = runSyncStarterManifestCli(process.argv.slice(2));\n process.exit(exitCode);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sync-builder-starter-manifest.js","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { _postProcessStandalone } from \"./create.js\";\n\nexport const STARTER_APP_NAME = \"builder-agent-native-starter\";\nexport const CHAT_TEMPLATE = \"chat\";\n\n/** Toolchain files that must track templates/chat or typecheck/build drift. */\nexport const STARTER_TOOLCHAIN_SYNC_PATHS = [\n \"react-router.config.ts\",\n \"vite.config.ts\",\n \"tsconfig.json\",\n \"ssr-entry.ts\",\n \"app/vite-env.d.ts\",\n \"app/routes.ts\",\n \"server/routes/[...page].get.ts\",\n // server/plugins/* are intentionally excluded: starter keeps its own\n // systemPrompt and auth marketing copy; post-process only rewrites appId/title.\n \"server/middleware/auth.ts\",\n \"components.json\",\n \".oxfmtrc.json\",\n \"netlify.toml\",\n] as const;\n\nexport type StarterToolchainSyncPath =\n (typeof STARTER_TOOLCHAIN_SYNC_PATHS)[number];\n\ntype PackageJson = Record<string, unknown>;\n\nexport type StandaloneChatSnapshot = {\n cleanup: () => void;\n dir: string;\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n toolchainFiles: Map<StarterToolchainSyncPath, string>;\n};\n\nexport function listStarterSyncPaths(): string[] {\n return [\n \"package.json\",\n \"pnpm-lock.yaml\",\n \"pnpm-workspace.yaml\",\n ...STARTER_TOOLCHAIN_SYNC_PATHS,\n ];\n}\n\nexport function findAgentNativeRoot(startDir = process.cwd()): string {\n let dir = path.resolve(startDir);\n for (let i = 0; i < 12; i++) {\n const chatPackageJson = path.join(\n dir,\n \"templates\",\n CHAT_TEMPLATE,\n \"package.json\",\n );\n if (fs.existsSync(chatPackageJson)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"Could not find agent-native repo root (expected templates/chat/package.json).\",\n );\n}\n\nexport function collectStarterToolchainFiles(\n canonicalDir: string,\n): Map<StarterToolchainSyncPath, string> {\n const files = new Map<StarterToolchainSyncPath, string>();\n for (const relativePath of STARTER_TOOLCHAIN_SYNC_PATHS) {\n const absolutePath = path.join(canonicalDir, relativePath);\n if (!fs.existsSync(absolutePath)) continue;\n files.set(relativePath, fs.readFileSync(absolutePath, \"utf-8\"));\n }\n return files;\n}\n\nexport function createStandaloneChatSnapshot(\n repoRoot?: string,\n): StandaloneChatSnapshot {\n const root = repoRoot ?? findAgentNativeRoot();\n const chatTemplateDir = path.join(root, \"templates\", CHAT_TEMPLATE);\n const tempDir = fs.mkdtempSync(\n path.join(os.tmpdir(), \"an-builder-starter-sync-\"),\n );\n\n fs.cpSync(chatTemplateDir, tempDir, { recursive: true });\n _postProcessStandalone(STARTER_APP_NAME, tempDir, CHAT_TEMPLATE);\n\n const packageJson = JSON.parse(\n fs.readFileSync(path.join(tempDir, \"package.json\"), \"utf-8\"),\n ) as PackageJson;\n\n const workspacePath = path.join(tempDir, \"pnpm-workspace.yaml\");\n const pnpmWorkspaceYaml = fs.existsSync(workspacePath)\n ? fs.readFileSync(workspacePath, \"utf-8\")\n : null;\n\n return {\n cleanup: () => {\n fs.rmSync(tempDir, { recursive: true, force: true });\n },\n dir: tempDir,\n packageJson,\n pnpmWorkspaceYaml,\n toolchainFiles: collectStarterToolchainFiles(tempDir),\n };\n}\n\nexport function generateStandaloneChatManifest(repoRoot?: string): {\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n} {\n const snapshot = createStandaloneChatSnapshot(repoRoot);\n try {\n return {\n packageJson: snapshot.packageJson,\n pnpmWorkspaceYaml: snapshot.pnpmWorkspaceYaml,\n };\n } finally {\n snapshot.cleanup();\n }\n}\n\nfunction mergePackageJsonRecords(\n canonical: Record<string, string> | undefined,\n starter: Record<string, string> | undefined,\n starterPinnedKeys: string[] = [],\n): Record<string, string> {\n const merged = { ...(canonical ?? {}) };\n for (const [key, value] of Object.entries(starter ?? {})) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n for (const key of starterPinnedKeys) {\n const pinned = starter?.[key];\n if (pinned) {\n merged[key] = pinned;\n }\n }\n return merged;\n}\n\nexport function mergeStarterManifest(\n starterPackageJson: PackageJson,\n canonicalPackageJson: PackageJson,\n): PackageJson {\n const merged = structuredClone(canonicalPackageJson) as PackageJson;\n\n merged.name = starterPackageJson.name ?? STARTER_APP_NAME;\n if (typeof starterPackageJson.displayName === \"string\") {\n merged.displayName = starterPackageJson.displayName;\n }\n if (typeof starterPackageJson.description === \"string\") {\n merged.description = starterPackageJson.description;\n }\n if (starterPackageJson.private !== undefined) {\n merged.private = starterPackageJson.private;\n }\n if (typeof starterPackageJson.packageManager === \"string\") {\n merged.packageManager = starterPackageJson.packageManager;\n }\n\n merged.dependencies = mergePackageJsonRecords(\n canonicalPackageJson.dependencies as Record<string, string> | undefined,\n starterPackageJson.dependencies as Record<string, string> | undefined,\n [\"@agent-native/core\"],\n );\n merged.devDependencies = mergePackageJsonRecords(\n canonicalPackageJson.devDependencies as Record<string, string> | undefined,\n starterPackageJson.devDependencies as Record<string, string> | undefined,\n );\n merged.scripts = mergePackageJsonRecords(\n canonicalPackageJson.scripts as Record<string, string> | undefined,\n starterPackageJson.scripts as Record<string, string> | undefined,\n );\n\n return merged;\n}\n\nexport function workspaceFileSyncChanged(\n existingWorkspace: string | null,\n canonicalWorkspace: string | null,\n): boolean {\n if (canonicalWorkspace === null) {\n return existingWorkspace !== null;\n }\n return existingWorkspace !== canonicalWorkspace;\n}\n\nexport function applyWorkspaceFileSync(\n targetPath: string,\n canonicalWorkspace: string | null,\n): void {\n if (canonicalWorkspace === null) {\n if (fs.existsSync(targetPath)) {\n fs.unlinkSync(targetPath);\n }\n return;\n }\n fs.writeFileSync(targetPath, canonicalWorkspace);\n}\n\nfunction stableJson(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nexport type StarterToolchainSyncChange = {\n relativePath: StarterToolchainSyncPath;\n changed: boolean;\n};\n\nexport function diffStarterToolchainFiles(\n starterDir: string,\n canonicalFiles: Map<StarterToolchainSyncPath, string>,\n): StarterToolchainSyncChange[] {\n return STARTER_TOOLCHAIN_SYNC_PATHS.map((relativePath) => {\n const canonicalContent = canonicalFiles.get(relativePath) ?? null;\n const targetPath = path.join(starterDir, relativePath);\n const existingContent = fs.existsSync(targetPath)\n ? fs.readFileSync(targetPath, \"utf-8\")\n : null;\n return {\n relativePath,\n changed: existingContent !== canonicalContent,\n };\n });\n}\n\nexport function applyStarterToolchainSync(\n starterDir: string,\n canonicalFiles: Map<StarterToolchainSyncPath, string>,\n): StarterToolchainSyncChange[] {\n const changes: StarterToolchainSyncChange[] = [];\n for (const relativePath of STARTER_TOOLCHAIN_SYNC_PATHS) {\n const canonicalContent = canonicalFiles.get(relativePath) ?? null;\n const targetPath = path.join(starterDir, relativePath);\n const existingContent = fs.existsSync(targetPath)\n ? fs.readFileSync(targetPath, \"utf-8\")\n : null;\n const changed = existingContent !== canonicalContent;\n if (changed) {\n if (canonicalContent === null) {\n if (fs.existsSync(targetPath)) {\n fs.unlinkSync(targetPath);\n }\n } else {\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, canonicalContent);\n }\n }\n changes.push({ relativePath, changed });\n }\n return changes;\n}\n\nexport type SyncStarterManifestResult = {\n changed: boolean;\n packageChanged: boolean;\n workspaceChanged: boolean;\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n toolchainChanges: StarterToolchainSyncChange[];\n changedToolchainPaths: StarterToolchainSyncPath[];\n};\n\nexport function resolveStarterPaths(options: {\n starterDir?: string;\n starterPackageJsonPath?: string;\n starterPnpmWorkspacePath?: string;\n}): {\n starterDir: string;\n starterPackageJsonPath: string;\n starterPnpmWorkspacePath: string;\n} {\n if (options.starterDir) {\n return {\n starterDir: path.resolve(options.starterDir),\n starterPackageJsonPath: path.join(\n path.resolve(options.starterDir),\n \"package.json\",\n ),\n starterPnpmWorkspacePath: path.join(\n path.resolve(options.starterDir),\n \"pnpm-workspace.yaml\",\n ),\n };\n }\n if (!options.starterPackageJsonPath) {\n throw new Error(\"Provide --starter-dir or --starter-package-json.\");\n }\n const starterPackageJsonPath = path.resolve(options.starterPackageJsonPath);\n return {\n starterDir: path.dirname(starterPackageJsonPath),\n starterPackageJsonPath,\n starterPnpmWorkspacePath:\n options.starterPnpmWorkspacePath ??\n path.join(path.dirname(starterPackageJsonPath), \"pnpm-workspace.yaml\"),\n };\n}\n\nexport function syncStarterManifestFiles(options: {\n starterDir?: string;\n starterPackageJsonPath?: string;\n starterPnpmWorkspacePath?: string;\n repoRoot?: string;\n write?: boolean;\n}): SyncStarterManifestResult {\n const { starterDir, starterPackageJsonPath, starterPnpmWorkspacePath } =\n resolveStarterPaths(options);\n const snapshot = createStandaloneChatSnapshot(options.repoRoot);\n\n try {\n const starterPackageJson = JSON.parse(\n fs.readFileSync(starterPackageJsonPath, \"utf-8\"),\n ) as PackageJson;\n const mergedPackageJson = mergeStarterManifest(\n starterPackageJson,\n snapshot.packageJson,\n );\n\n const existingWorkspace = fs.existsSync(starterPnpmWorkspacePath)\n ? fs.readFileSync(starterPnpmWorkspacePath, \"utf-8\")\n : null;\n\n const workspaceChanged = workspaceFileSyncChanged(\n existingWorkspace,\n snapshot.pnpmWorkspaceYaml,\n );\n const packageChanged =\n stableJson(starterPackageJson) !== stableJson(mergedPackageJson);\n const toolchainChanges = diffStarterToolchainFiles(\n starterDir,\n snapshot.toolchainFiles,\n );\n const changedToolchainPaths = toolchainChanges\n .filter((change) => change.changed)\n .map((change) => change.relativePath);\n const changed =\n packageChanged || workspaceChanged || changedToolchainPaths.length > 0;\n\n if (options.write && changed) {\n if (packageChanged) {\n fs.writeFileSync(starterPackageJsonPath, stableJson(mergedPackageJson));\n }\n if (workspaceChanged) {\n applyWorkspaceFileSync(\n starterPnpmWorkspacePath,\n snapshot.pnpmWorkspaceYaml,\n );\n }\n if (changedToolchainPaths.length > 0) {\n applyStarterToolchainSync(starterDir, snapshot.toolchainFiles);\n }\n }\n\n return {\n changed,\n packageChanged,\n workspaceChanged,\n packageJson: mergedPackageJson,\n pnpmWorkspaceYaml: snapshot.pnpmWorkspaceYaml,\n toolchainChanges,\n changedToolchainPaths,\n };\n } finally {\n snapshot.cleanup();\n }\n}\n\nexport function parseSyncStarterManifestArgs(argv: string[]): {\n command: \"merge\" | \"generate\" | \"paths\";\n starterDir?: string;\n starterPackageJsonPath?: string;\n starterPnpmWorkspacePath?: string;\n write: boolean;\n repoRoot?: string;\n} {\n const [commandRaw, ...rest] = argv;\n const command =\n commandRaw === \"generate\"\n ? \"generate\"\n : commandRaw === \"paths\"\n ? \"paths\"\n : \"merge\";\n let starterDir: string | undefined;\n let starterPackageJsonPath: string | undefined;\n let starterPnpmWorkspacePath: string | undefined;\n let write = false;\n let repoRoot: string | undefined;\n\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n if (arg === \"--write\") {\n write = true;\n continue;\n }\n if (arg === \"--starter-dir\") {\n starterDir = rest[++i];\n continue;\n }\n if (arg === \"--starter-package-json\") {\n starterPackageJsonPath = rest[++i];\n continue;\n }\n if (arg === \"--starter-pnpm-workspace\") {\n starterPnpmWorkspacePath = rest[++i];\n continue;\n }\n if (arg === \"--repo-root\") {\n repoRoot = rest[++i];\n continue;\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n if (command === \"merge\" && !starterDir && !starterPackageJsonPath) {\n throw new Error(\n \"merge requires --starter-dir <path> or --starter-package-json <path> [--starter-pnpm-workspace <path>] [--write] [--repo-root <path>]\",\n );\n }\n\n return {\n command,\n starterDir,\n starterPackageJsonPath,\n starterPnpmWorkspacePath,\n write,\n repoRoot,\n };\n}\n\nexport function runSyncStarterManifestCli(argv: string[]): number {\n const args = parseSyncStarterManifestArgs(argv);\n\n if (args.command === \"generate\") {\n const { packageJson, pnpmWorkspaceYaml } = generateStandaloneChatManifest(\n args.repoRoot,\n );\n process.stdout.write(stableJson(packageJson));\n if (pnpmWorkspaceYaml) {\n process.stdout.write(\"\\n--- pnpm-workspace.yaml ---\\n\");\n process.stdout.write(pnpmWorkspaceYaml);\n }\n return 0;\n }\n\n if (args.command === \"paths\") {\n for (const syncPath of listStarterSyncPaths()) {\n process.stdout.write(`${syncPath}\\n`);\n }\n return 0;\n }\n\n const result = syncStarterManifestFiles({\n starterDir: args.starterDir,\n starterPackageJsonPath: args.starterPackageJsonPath,\n starterPnpmWorkspacePath: args.starterPnpmWorkspacePath,\n repoRoot: args.repoRoot,\n write: args.write,\n });\n\n if (result.changed) {\n const updatedPaths = [\n ...(result.packageChanged ? [\"package.json\"] : []),\n ...(result.workspaceChanged ? [\"pnpm-workspace.yaml\"] : []),\n ...result.changedToolchainPaths,\n ];\n const summary = updatedPaths.length ? ` (${updatedPaths.join(\", \")})` : \"\";\n console.log(\n args.write\n ? `Updated builder-agent-native-starter from templates/chat${summary}.`\n : `builder-agent-native-starter is out of date with templates/chat${summary}.`,\n );\n return args.write ? 0 : 1;\n }\n\n console.log(\"builder-agent-native-starter already matches templates/chat.\");\n return 0;\n}\n\nconst isDirectRun =\n process.argv[1] &&\n path.resolve(process.argv[1]) ===\n path.resolve(fileURLToPath(import.meta.url));\n\nif (isDirectRun) {\n const exitCode = runSyncStarterManifestCli(process.argv.slice(2));\n process.exit(exitCode);\n}\n"]}
|
|
@@ -42,7 +42,7 @@ export declare function cleanExpired(map: Map<number, AwarenessEntry>): void;
|
|
|
42
42
|
*
|
|
43
43
|
* Client sends its awareness state and receives other clients' states.
|
|
44
44
|
*
|
|
45
|
-
* Body: { clientId: number, state: string (
|
|
45
|
+
* Body: { clientId: number, state: string | null (JSON-encoded awareness state, or null to clear) }
|
|
46
46
|
* Response: { states: Array<{ clientId: number, state: string }> }
|
|
47
47
|
*/
|
|
48
48
|
export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;
|
|
1
|
+
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;kBAuCa,MAAM;eAAS,MAAM;;GAa1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;kBAWM,MAAM;kBAAY,MAAM;;GAMvD,CAAC"}
|
package/dist/collab/awareness.js
CHANGED
|
@@ -64,7 +64,7 @@ function pruneIfEmpty(docId, map) {
|
|
|
64
64
|
*
|
|
65
65
|
* Client sends its awareness state and receives other clients' states.
|
|
66
66
|
*
|
|
67
|
-
* Body: { clientId: number, state: string (
|
|
67
|
+
* Body: { clientId: number, state: string | null (JSON-encoded awareness state, or null to clear) }
|
|
68
68
|
* Response: { states: Array<{ clientId: number, state: string }> }
|
|
69
69
|
*/
|
|
70
70
|
export const postAwareness = defineEventHandler(async (event) => {
|
|
@@ -75,22 +75,26 @@ export const postAwareness = defineEventHandler(async (event) => {
|
|
|
75
75
|
}
|
|
76
76
|
const body = await readBody(event);
|
|
77
77
|
const { clientId, state } = body;
|
|
78
|
-
if (clientId == null ||
|
|
78
|
+
if (clientId == null || state === undefined) {
|
|
79
79
|
// `!clientId` would wrongly reject clientId === 0, which is a valid
|
|
80
|
-
// (if rare) Yjs client id.
|
|
80
|
+
// (if rare) Yjs client id. A null state is valid: it clears this client.
|
|
81
81
|
setResponseStatus(event, 400);
|
|
82
82
|
return { error: "clientId and state required" };
|
|
83
83
|
}
|
|
84
84
|
const map = getDocAwareness(docId);
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
if (state === null) {
|
|
86
|
+
map.delete(clientId);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Store this client's state
|
|
90
|
+
map.set(clientId, { clientId, state, lastSeen: Date.now() });
|
|
91
|
+
}
|
|
87
92
|
// Clean expired entries, then prune the outer-map entry if it becomes empty.
|
|
88
93
|
// Without pruning, a deployment with many transient docIds (e.g. one per
|
|
89
94
|
// session) would grow _awarenessMap without bound.
|
|
90
95
|
cleanExpired(map);
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
// that was immediately evicted by a concurrent cleanExpired run).
|
|
96
|
+
// Null-state clears and expiry can empty the map; prune the outer entry so
|
|
97
|
+
// transient document ids do not accumulate.
|
|
94
98
|
pruneIfEmpty(docId, map);
|
|
95
99
|
// Build the full list of current states (all clients including sender).
|
|
96
100
|
const allStates = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.js","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAG3E,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,aAAa;AAQ/C,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,8EAA8E;AAE9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAA2B,CAAC;AAclE,MAAM,iBAAiB,GAAG,IAAI,YAAY,EAAE,CAAC;AAC7C,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,mBAAmB;IACjC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAAkD,EAClD,KAAc,EACd,KAAc;IAEd,MAAM,KAAK,GAAyB;QAClC,MAAM,EAAE,WAAW;QACnB,IAAI,EAAE,kBAAkB;QACxB,KAAK;QACL,MAAM;QACN,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;KACxB,CAAC;IACF,iBAAiB,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,wCAAwC;AACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuC,CAAC;AAErE,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QAChB,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAgC;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;QACpC,IAAI,GAAG,GAAG,KAAK,CAAC,QAAQ,GAAG,iBAAiB,EAAE,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,0EAA0E;AAC1E,SAAS,YAAY,CAAC,KAAa,EAAE,GAAgC;IACnE,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnB,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAG3B,CAAC;IAEF,IAAI,QAAQ,IAAI,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"awareness.js","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Server-side awareness state management for collaborative editing.\n *\n * Stores per-client awareness state (cursor positions, user info) in memory.\n * Clients POST their state and receive other clients' states via polling.\n * States expire after 30 seconds of no updates.\n *\n * Fast-path: when a client POSTs new awareness state, the server emits an\n * event on the awareness emitter so SSE-connected peers receive cursor moves\n * push-style instead of waiting for the next poll cycle.\n */\n\nimport { EventEmitter } from \"node:events\";\n\nimport { defineEventHandler, setResponseStatus, getRouterParam } from \"h3\";\nimport type { H3Event } from \"h3\";\n\nimport { readBody } from \"../server/h3-helpers.js\";\n\nconst AWARENESS_TIMEOUT = 30_000; // 30 seconds\n\nexport interface AwarenessEntry {\n clientId: number;\n state: string; // JSON-encoded awareness state object\n lastSeen: number;\n}\n\n// ---------------------------------------------------------------------------\n// Awareness event emitter — fast-path for push delivery to SSE-connected peers.\n// The SSE handler (poll-events) subscribes and forwards events to its stream.\n// ---------------------------------------------------------------------------\n\nexport const AWARENESS_CHANGE_EVENT = \"awareness-change\" as const;\n\nexport interface AwarenessChangeEvent {\n source: \"awareness\";\n type: \"awareness-change\";\n docId: string;\n /** Array of updated states for this document (all non-expired clients). */\n states: Array<{ clientId: number; state: string }>;\n /** Owner email for access-scoped delivery (taken from session if available). */\n owner?: string;\n /** Org ID for org-scoped delivery. */\n orgId?: string;\n}\n\nconst _awarenessEmitter = new EventEmitter();\n_awarenessEmitter.setMaxListeners(0);\n\nexport function getAwarenessEmitter(): EventEmitter {\n return _awarenessEmitter;\n}\n\nexport function emitAwarenessChange(\n docId: string,\n states: Array<{ clientId: number; state: string }>,\n owner?: string,\n orgId?: string,\n): void {\n const event: AwarenessChangeEvent = {\n source: \"awareness\",\n type: \"awareness-change\",\n docId,\n states,\n ...(owner && { owner }),\n ...(orgId && { orgId }),\n };\n _awarenessEmitter.emit(AWARENESS_CHANGE_EVENT, event);\n}\n\n// docId → Map<clientId, AwarenessEntry>\nconst _awarenessMap = new Map<string, Map<number, AwarenessEntry>>();\n\nexport function getDocAwareness(docId: string): Map<number, AwarenessEntry> {\n let map = _awarenessMap.get(docId);\n if (!map) {\n map = new Map();\n _awarenessMap.set(docId, map);\n }\n return map;\n}\n\nexport function cleanExpired(map: Map<number, AwarenessEntry>): void {\n const now = Date.now();\n for (const [clientId, entry] of map) {\n if (now - entry.lastSeen > AWARENESS_TIMEOUT) {\n map.delete(clientId);\n }\n }\n}\n\n// Drop the per-document map from the registry once it has no entries left,\n// so the outer map does not grow unbounded with every docId ever touched.\nfunction pruneIfEmpty(docId: string, map: Map<number, AwarenessEntry>): void {\n if (map.size === 0) {\n _awarenessMap.delete(docId);\n }\n}\n\n/**\n * POST /_agent-native/collab/:docId/awareness\n *\n * Client sends its awareness state and receives other clients' states.\n *\n * Body: { clientId: number, state: string | null (JSON-encoded awareness state, or null to clear) }\n * Response: { states: Array<{ clientId: number, state: string }> }\n */\nexport const postAwareness = defineEventHandler(async (event: H3Event) => {\n const docId = getRouterParam(event, \"docId\");\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const body = await readBody(event);\n const { clientId, state } = body as {\n clientId?: number;\n state?: string | null;\n };\n\n if (clientId == null || state === undefined) {\n // `!clientId` would wrongly reject clientId === 0, which is a valid\n // (if rare) Yjs client id. A null state is valid: it clears this client.\n setResponseStatus(event, 400);\n return { error: \"clientId and state required\" };\n }\n\n const map = getDocAwareness(docId);\n\n if (state === null) {\n map.delete(clientId);\n } else {\n // Store this client's state\n map.set(clientId, { clientId, state, lastSeen: Date.now() });\n }\n\n // Clean expired entries, then prune the outer-map entry if it becomes empty.\n // Without pruning, a deployment with many transient docIds (e.g. one per\n // session) would grow _awarenessMap without bound.\n cleanExpired(map);\n // Null-state clears and expiry can empty the map; prune the outer entry so\n // transient document ids do not accumulate.\n pruneIfEmpty(docId, map);\n\n // Build the full list of current states (all clients including sender).\n const allStates: Array<{ clientId: number; state: string }> = [];\n const otherStates: Array<{ clientId: number; state: string }> = [];\n for (const [id, entry] of map) {\n allStates.push({ clientId: id, state: entry.state });\n if (id !== clientId) {\n otherStates.push({ clientId: id, state: entry.state });\n }\n }\n\n // Fast-path: push the updated state set to SSE-connected peers so they\n // don't have to wait for the next poll cycle for cursor/selection updates.\n emitAwarenessChange(docId, allStates);\n\n return { states: otherStates };\n});\n\n/**\n * GET /_agent-native/collab/:docId/users\n *\n * Returns the list of active users for a document (for presence bar).\n */\nexport const getActiveUsers = defineEventHandler(async (event: H3Event) => {\n const docId = getRouterParam(event, \"docId\");\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const map = getDocAwareness(docId);\n cleanExpired(map);\n pruneIfEmpty(docId, map);\n\n const users: Array<{ clientId: number; lastSeen: number }> = [];\n for (const [, entry] of map) {\n users.push({ clientId: entry.clientId, lastSeen: entry.lastSeen });\n }\n\n return { users };\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/collab/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAKzB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,IAAI,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAC;CACvB;AAgBD,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAYD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAY1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,CA6BT;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,uBAAuB,EAAE,GACtC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B3D;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/collab/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAKzB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,IAAI,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAC;CACvB;AAgBD,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAYD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAY1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,CA6BT;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,uBAAuB,EAAE,GACtC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B3D;AA6ED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,0BAA0B,GAClC,yBAAyB,CAgpB3B"}
|
package/dist/collab/client.js
CHANGED
|
@@ -197,12 +197,13 @@ function scheduleAwarenessPush(baseUrl, docId, clientId, getState) {
|
|
|
197
197
|
const timer = setTimeout(() => {
|
|
198
198
|
_awarenessThrottleTimers.delete(key);
|
|
199
199
|
const state = getState();
|
|
200
|
-
if (!state)
|
|
201
|
-
return;
|
|
202
200
|
fetch(`${baseUrl}/${docId}/awareness`, {
|
|
203
201
|
method: "POST",
|
|
204
202
|
headers: { "Content-Type": "application/json" },
|
|
205
|
-
body: JSON.stringify({
|
|
203
|
+
body: JSON.stringify({
|
|
204
|
+
clientId,
|
|
205
|
+
state: state ? JSON.stringify(state) : null,
|
|
206
|
+
}),
|
|
206
207
|
}).catch(() => { }); // best-effort; poll cycle is the baseline fallback
|
|
207
208
|
}, 150);
|
|
208
209
|
_awarenessThrottleTimers.set(key, timer);
|