@jxsuite/studio 0.35.0 → 0.36.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.
- package/dist/studio.js +848 -208
- package/dist/studio.js.map +15 -10
- package/package.json +8 -5
- package/src/panels/ai-panel.ts +25 -3
- package/src/panels/toolbar.ts +2 -0
- package/src/panels/welcome-screen.ts +26 -0
- package/src/platforms/cloud.ts +774 -0
- package/src/platforms/devserver.ts +70 -0
- package/src/project-list.ts +38 -0
- package/src/publish/pages-service.ts +186 -0
- package/src/publish/publish-panel.ts +360 -0
- package/src/services/ai-models.ts +30 -1
- package/src/services/cf-settings.ts +58 -0
- package/src/services/settings-store.ts +7 -1
- package/src/studio.ts +8 -0
- package/src/types.ts +87 -174
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/studio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"description": "Jx Studio — visual builder for Jx documents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
".": "./src/studio.ts",
|
|
19
19
|
"./platform": "./src/platform.ts",
|
|
20
20
|
"./types": "./src/types.ts",
|
|
21
|
-
"./import-client": "./src/services/import-client.ts"
|
|
21
|
+
"./import-client": "./src/services/import-client.ts",
|
|
22
|
+
"./platforms/cloud": "./src/platforms/cloud.ts"
|
|
22
23
|
},
|
|
23
24
|
"publishConfig": {
|
|
24
25
|
"provenance": true
|
|
@@ -38,9 +39,11 @@
|
|
|
38
39
|
"@atlaskit/pragmatic-drag-and-drop": "^2.0.1",
|
|
39
40
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^2.0.0",
|
|
40
41
|
"@jxsuite/ai": "^0.33.0",
|
|
41
|
-
"@jxsuite/
|
|
42
|
-
"@jxsuite/
|
|
43
|
-
"@jxsuite/
|
|
42
|
+
"@jxsuite/create": "^0.36.0",
|
|
43
|
+
"@jxsuite/parser": "^0.35.1",
|
|
44
|
+
"@jxsuite/protocol": "^0.2.0",
|
|
45
|
+
"@jxsuite/runtime": "^0.34.2",
|
|
46
|
+
"@jxsuite/schema": "^0.35.0",
|
|
44
47
|
"@spectrum-web-components/accordion": "^1.12.1",
|
|
45
48
|
"@spectrum-web-components/action-bar": "1.12.1",
|
|
46
49
|
"@spectrum-web-components/action-button": "^1.12.1",
|
package/src/panels/ai-panel.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type { TemplateResult } from "lit-html";
|
|
|
21
21
|
import { effect, effectScope } from "../reactivity";
|
|
22
22
|
import { createDocumentAssistant } from "../services/document-assistant";
|
|
23
23
|
import { hasOpenAiKey } from "../services/ai-settings";
|
|
24
|
+
import { fetchAvailableModels, isProxyConfigured } from "../services/ai-models";
|
|
24
25
|
import { createAiCredentialsForm } from "../ui/ai-credentials-form";
|
|
25
26
|
import { clearMarkdownCache } from "./ai-chat/chat-markdown";
|
|
26
27
|
import { renderChatHeader, renderMessageList } from "./ai-chat/chat-view";
|
|
@@ -36,6 +37,23 @@ let mounted = false;
|
|
|
36
37
|
/** Whether the OpenAI key form is showing (gate when no key, or re-edit via the gear). */
|
|
37
38
|
let keyEditing = false;
|
|
38
39
|
|
|
40
|
+
/**
|
|
41
|
+
* One-time proxy probe: managed platforms (cloud Workers AI) and env-keyed dev servers report
|
|
42
|
+
* `configured` from /models, unlocking the assistant without a locally stored key. Fired lazily on
|
|
43
|
+
* the first gated render.
|
|
44
|
+
*/
|
|
45
|
+
let proxyProbe: Promise<void> | null = null;
|
|
46
|
+
|
|
47
|
+
function ensureProxyProbe() {
|
|
48
|
+
proxyProbe ??= fetchAvailableModels({ force: true })
|
|
49
|
+
.catch(() => {
|
|
50
|
+
// Unreachable proxy — the key gate stays up.
|
|
51
|
+
})
|
|
52
|
+
.then(() => {
|
|
53
|
+
scheduleAiRender();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
39
57
|
/** Which pane the panel shows once the key gate is passed. */
|
|
40
58
|
let view: "chat" | "sessions" = "chat";
|
|
41
59
|
|
|
@@ -245,9 +263,13 @@ const composer = createComposer({
|
|
|
245
263
|
|
|
246
264
|
/** @returns {TemplateResult} */
|
|
247
265
|
export function renderAiPanelTemplate(): TemplateResult {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
266
|
+
/* The document assistant authenticates via the AI proxy. Gate the chat
|
|
267
|
+
behind the key form until a key is stored locally OR the proxy reports
|
|
268
|
+
itself configured (managed platforms, env-keyed dev servers). */
|
|
269
|
+
if ((!hasOpenAiKey() && !isProxyConfigured()) || keyEditing) {
|
|
270
|
+
if (!keyEditing) {
|
|
271
|
+
ensureProxyProbe();
|
|
272
|
+
}
|
|
251
273
|
return renderKeyGate();
|
|
252
274
|
}
|
|
253
275
|
|
package/src/panels/toolbar.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { html, render as litRender, nothing } from "lit-html";
|
|
8
|
+
import { openPublishPanel } from "../publish/publish-panel";
|
|
8
9
|
import { updateSession } from "../store";
|
|
9
10
|
import { redo as tabRedo, undo as tabUndo } from "../tabs/transact";
|
|
10
11
|
import { effect, effectScope } from "../reactivity";
|
|
@@ -472,6 +473,7 @@ function toolbarTemplate() {
|
|
|
472
473
|
${recentProjectsTpl}
|
|
473
474
|
</div>
|
|
474
475
|
${tbBtnTpl("Manage", openBrowseModal, "sp-icon-view-list")}
|
|
476
|
+
${tbBtnTpl("Publish", openPublishPanel)}
|
|
475
477
|
<sp-action-button size="s" title="Save" ?disabled=${!canSave} @click=${ctx.saveFile}>
|
|
476
478
|
${toolbarIconMap["sp-icon-save-floppy"]}<span class="tb-label">Save</span>
|
|
477
479
|
</sp-action-button>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { html, render as litRender, nothing } from "lit-html";
|
|
8
|
+
import { getProjectList } from "../project-list";
|
|
8
9
|
import { clearRecentProjects, getRecentProjects, removeRecentProject } from "../recent-projects";
|
|
9
10
|
import { renderOnly } from "../store";
|
|
10
11
|
import { platformSupportsClone } from "./git-panel";
|
|
@@ -27,6 +28,8 @@ export function initWelcome(ctx: WelcomeCtx) {
|
|
|
27
28
|
export function renderWelcome(host: HTMLElement) {
|
|
28
29
|
const ctx = _ctx as WelcomeCtx;
|
|
29
30
|
const recent = getRecentProjects();
|
|
31
|
+
// Catalogue entries already in Recent stay in that section only.
|
|
32
|
+
const catalogue = getProjectList().filter((p) => !recent.some((r) => r.root === p.root));
|
|
30
33
|
const showClone = platformSupportsClone();
|
|
31
34
|
|
|
32
35
|
litRender(
|
|
@@ -84,6 +87,29 @@ export function renderWelcome(host: HTMLElement) {
|
|
|
84
87
|
: nothing}
|
|
85
88
|
</div>
|
|
86
89
|
|
|
90
|
+
${catalogue.length > 0
|
|
91
|
+
? html`
|
|
92
|
+
<div class="welcome-section">
|
|
93
|
+
<h2 class="welcome-section-title">Projects</h2>
|
|
94
|
+
${catalogue.map(
|
|
95
|
+
(p) => html`
|
|
96
|
+
<div class="welcome-recent-row">
|
|
97
|
+
<button
|
|
98
|
+
class="welcome-recent welcome-catalogue"
|
|
99
|
+
@click=${() => ctx.openRecentProject(p.root)}
|
|
100
|
+
title=${p.root}
|
|
101
|
+
>
|
|
102
|
+
<span class="welcome-recent-name">${p.name}</span>
|
|
103
|
+
<span class="welcome-recent-path">
|
|
104
|
+
${p.description ?? shortenPath(p.root)}
|
|
105
|
+
</span>
|
|
106
|
+
</button>
|
|
107
|
+
</div>
|
|
108
|
+
`,
|
|
109
|
+
)}
|
|
110
|
+
</div>
|
|
111
|
+
`
|
|
112
|
+
: nothing}
|
|
87
113
|
${recent.length > 0
|
|
88
114
|
? html`
|
|
89
115
|
<div class="welcome-section">
|