aimeat 1.25.0 → 1.26.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/README.md +8 -1
- package/dist/locales/en.json +144 -0
- package/dist/locales/fi.json +144 -0
- package/dist/public/components/ImageDeliverable.js +2 -1
- package/dist/public/components/Modal.js +3 -2
- package/dist/public/components/NotificationBell.js +2 -1
- package/dist/public/components/PresenceDot.js +53 -0
- package/dist/public/css/components/markdown.css +67 -0
- package/dist/public/css/theme.css +30 -0
- package/dist/public/css/views/notebook.css +195 -0
- package/dist/public/css/views/profile.css +15 -0
- package/dist/public/js/api.js +5 -3
- package/dist/public/js/components/auth-image.js +3 -2
- package/dist/public/js/components/tag-cloud.js +1 -1
- package/dist/public/js/components/tag-editor.js +1 -1
- package/dist/public/js/hooks.js +1 -2
- package/dist/public/js/presence-store.js +97 -0
- package/dist/public/js/services/admin.js +14 -5
- package/dist/public/js/services/boards.js +1 -1
- package/dist/public/js/services/ecosystem.js +1 -1
- package/dist/public/js/services/foundry-prompts-base.js +2 -2
- package/dist/public/js/services/foundry-smoke.js +2 -1
- package/dist/public/js/services/foundry-validate.js +6 -8
- package/dist/public/js/services/foundry.js +4 -3
- package/dist/public/js/services/generator-prompts-base.js +2 -2
- package/dist/public/js/services/generator-smoke.js +2 -1
- package/dist/public/js/services/generator-validate.js +5 -7
- package/dist/public/js/services/generator.js +2 -1
- package/dist/public/js/services/memory.js +13 -0
- package/dist/public/js/services/messages.js +2 -1
- package/dist/public/js/services/notebook.js +124 -0
- package/dist/public/js/services/packages.js +3 -2
- package/dist/public/js/services/presence.js +35 -0
- package/dist/public/js/style-testbed.js +6 -5
- package/dist/public/lib/minidenticons.min.js +1 -0
- package/dist/public/lib/yaml.mjs +1 -0
- package/dist/public/spa.html +90 -8
- package/dist/public/types/aimeat-globals.d.ts +52 -0
- package/dist/public/types/vendored-libs.d.ts +56 -0
- package/dist/public/views/_template.js +3 -1
- package/dist/public/views/admin/agent-integration-tab.js +4 -3
- package/dist/public/views/admin/agents-tab.js +3 -2
- package/dist/public/views/admin/config-tab.js +4 -3
- package/dist/public/views/admin/economy-tab.js +4 -3
- package/dist/public/views/admin/federation-tab.js +138 -1
- package/dist/public/views/admin/maintenance-tab.js +1 -1
- package/dist/public/views/admin/messages-tab.js +115 -0
- package/dist/public/views/admin/overview-tab.js +4 -3
- package/dist/public/views/admin/portal-tab.js +90 -2
- package/dist/public/views/admin/push-tab.js +8 -6
- package/dist/public/views/admin/security-tab.js +7 -7
- package/dist/public/views/admin.js +29 -9
- package/dist/public/views/doc-solo.js +3 -1
- package/dist/public/views/guides.js +8 -4
- package/dist/public/views/hobbies.js +4 -2
- package/dist/public/views/marketplace.js +10 -9
- package/dist/public/views/openclaw.js +1 -1
- package/dist/public/views/portal-dev.js +5 -2
- package/dist/public/views/portal.js +3 -2
- package/dist/public/views/profile/agents/shared-board.js +4 -2
- package/dist/public/views/profile/agents/tab-messages.js +13 -11
- package/dist/public/views/profile/agents-messages-subtab.js +2 -1
- package/dist/public/views/profile/apps-tab.js +2 -1
- package/dist/public/views/profile/boards-tab.js +3 -2
- package/dist/public/views/profile/calibrator-batch.js +3 -2
- package/dist/public/views/profile/data-wallet-tab.js +2 -1
- package/dist/public/views/profile/extensions-tab.js +4 -3
- package/dist/public/views/profile/federation-tab.js +4 -0
- package/dist/public/views/profile/foundry-dashboard/use-autopilot.js +3 -2
- package/dist/public/views/profile/foundry-detail.js +1 -1
- package/dist/public/views/profile/generator-detail.js +1 -1
- package/dist/public/views/profile/inbox-tab.js +7 -3
- package/dist/public/views/profile/inline-panels.js +3 -1
- package/dist/public/views/profile/knowledge-tab.js +2 -1
- package/dist/public/views/profile/landing-page.js +88 -0
- package/dist/public/views/profile/memory-tab.js +6 -5
- package/dist/public/views/profile/notebook-tab.js +500 -0
- package/dist/public/views/profile/organisms/activity-panel.js +135 -0
- package/dist/public/views/profile/organisms/agents.js +141 -0
- package/dist/public/views/profile/organisms/document.js +274 -0
- package/dist/public/views/profile/organisms/helpers.js +61 -0
- package/dist/public/views/profile/organisms/home.js +315 -0
- package/dist/public/views/profile/organisms/members.js +220 -0
- package/dist/public/views/profile/organisms/panels.js +173 -0
- package/dist/public/views/profile/organisms/participants-panel.js +160 -0
- package/dist/public/views/profile/organisms/schema-form.js +127 -0
- package/dist/public/views/profile/organisms/sources-panel.js +164 -0
- package/dist/public/views/profile/organisms/widgets.js +58 -0
- package/dist/public/views/profile/organisms/workspace-comments.js +99 -0
- package/dist/public/views/profile/organisms/workspace-list.js +268 -0
- package/dist/public/views/profile/organisms/workspace.js +1272 -0
- package/dist/public/views/profile/organisms-tab.js +456 -3819
- package/dist/public/views/profile/shared.js +64 -2
- package/dist/public/views/profile/workflows-form.js +1 -1
- package/dist/public/views/profile.js +16 -14
- package/dist/public/views/public-knowledge-viewer.js +3 -2
- package/dist/public/views/public-workspace-viewer.js +2 -1
- package/dist/scripts/check-importmap.d.ts +2 -0
- package/dist/scripts/check-importmap.d.ts.map +1 -0
- package/dist/scripts/check-importmap.js +102 -0
- package/dist/scripts/check-importmap.js.map +1 -0
- package/dist/src/cli/scaffold.d.ts +26 -3
- package/dist/src/cli/scaffold.d.ts.map +1 -1
- package/dist/src/cli/scaffold.js +33 -3
- package/dist/src/cli/scaffold.js.map +1 -1
- package/dist/src/config.d.ts +10 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +5 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +927 -11
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/generated/prisma-postgres/edge.js +32 -6
- package/dist/src/generated/prisma-postgres/index-browser.js +29 -3
- package/dist/src/generated/prisma-postgres/index.d.ts +1970 -160
- package/dist/src/generated/prisma-postgres/index.js +32 -6
- package/dist/src/generated/prisma-postgres/package.json +1 -1
- package/dist/src/generated/prisma-postgres/schema.prisma +45 -12
- package/dist/src/generated/prisma-postgres/wasm.js +32 -6
- package/dist/src/index.js +36 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/routes/admin-monitoring.d.ts.map +1 -1
- package/dist/src/routes/admin-monitoring.js +8 -0
- package/dist/src/routes/admin-monitoring.js.map +1 -1
- package/dist/src/routes/federation-peer.d.ts.map +1 -1
- package/dist/src/routes/federation-peer.js +327 -43
- package/dist/src/routes/federation-peer.js.map +1 -1
- package/dist/src/routes/federation-sync.d.ts +2 -0
- package/dist/src/routes/federation-sync.d.ts.map +1 -1
- package/dist/src/routes/federation-sync.js +20 -1
- package/dist/src/routes/federation-sync.js.map +1 -1
- package/dist/src/routes/librarian.d.ts +18 -0
- package/dist/src/routes/librarian.d.ts.map +1 -0
- package/dist/src/routes/librarian.js +88 -0
- package/dist/src/routes/librarian.js.map +1 -0
- package/dist/src/routes/messages.d.ts.map +1 -1
- package/dist/src/routes/messages.js +2 -1
- package/dist/src/routes/messages.js.map +1 -1
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +9 -1
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/presence.d.ts +23 -0
- package/dist/src/routes/presence.d.ts.map +1 -0
- package/dist/src/routes/presence.js +88 -0
- package/dist/src/routes/presence.js.map +1 -0
- package/dist/src/routes/site.d.ts +12 -0
- package/dist/src/routes/site.d.ts.map +1 -1
- package/dist/src/routes/site.js +45 -1
- package/dist/src/routes/site.js.map +1 -1
- package/dist/src/routes/sse.d.ts +2 -0
- package/dist/src/routes/sse.d.ts.map +1 -1
- package/dist/src/routes/sse.js +9 -0
- package/dist/src/routes/sse.js.map +1 -1
- package/dist/src/routes/wellknown.d.ts.map +1 -1
- package/dist/src/routes/wellknown.js +5 -0
- package/dist/src/routes/wellknown.js.map +1 -1
- package/dist/src/routes/work.d.ts.map +1 -1
- package/dist/src/routes/work.js +6 -0
- package/dist/src/routes/work.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +13 -0
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
- package/dist/src/server-bootstrap/service-init.js +34 -0
- package/dist/src/server-bootstrap/service-init.js.map +1 -1
- package/dist/src/services/config-schema.d.ts.map +1 -1
- package/dist/src/services/config-schema.js +2 -0
- package/dist/src/services/config-schema.js.map +1 -1
- package/dist/src/services/federation-availability.d.ts +28 -0
- package/dist/src/services/federation-availability.d.ts.map +1 -0
- package/dist/src/services/federation-availability.js +58 -0
- package/dist/src/services/federation-availability.js.map +1 -0
- package/dist/src/services/federation-book.d.ts +70 -0
- package/dist/src/services/federation-book.d.ts.map +1 -0
- package/dist/src/services/federation-book.js +198 -0
- package/dist/src/services/federation-book.js.map +1 -0
- package/dist/src/services/federation-tiers.d.ts +45 -0
- package/dist/src/services/federation-tiers.d.ts.map +1 -0
- package/dist/src/services/federation-tiers.js +58 -0
- package/dist/src/services/federation-tiers.js.map +1 -0
- package/dist/src/services/federation.d.ts +15 -0
- package/dist/src/services/federation.d.ts.map +1 -1
- package/dist/src/services/federation.js +12 -0
- package/dist/src/services/federation.js.map +1 -1
- package/dist/src/services/librarian.d.ts +62 -0
- package/dist/src/services/librarian.d.ts.map +1 -0
- package/dist/src/services/librarian.js +135 -0
- package/dist/src/services/librarian.js.map +1 -0
- package/dist/src/services/message-delivery.d.ts +3 -1
- package/dist/src/services/message-delivery.d.ts.map +1 -1
- package/dist/src/services/message-delivery.js +23 -2
- package/dist/src/services/message-delivery.js.map +1 -1
- package/dist/src/services/network-policy.d.ts +88 -0
- package/dist/src/services/network-policy.d.ts.map +1 -0
- package/dist/src/services/network-policy.js +154 -0
- package/dist/src/services/network-policy.js.map +1 -0
- package/dist/src/services/notebook-classify-prompt.d.ts +15 -0
- package/dist/src/services/notebook-classify-prompt.d.ts.map +1 -0
- package/dist/src/services/notebook-classify-prompt.js +39 -0
- package/dist/src/services/notebook-classify-prompt.js.map +1 -0
- package/dist/src/services/notebook-classify.d.ts +80 -0
- package/dist/src/services/notebook-classify.d.ts.map +1 -0
- package/dist/src/services/notebook-classify.js +150 -0
- package/dist/src/services/notebook-classify.js.map +1 -0
- package/dist/src/services/presence.d.ts +108 -0
- package/dist/src/services/presence.d.ts.map +1 -0
- package/dist/src/services/presence.js +304 -0
- package/dist/src/services/presence.js.map +1 -0
- package/dist/src/services/prompt-defaults.d.ts.map +1 -1
- package/dist/src/services/prompt-defaults.js +13 -0
- package/dist/src/services/prompt-defaults.js.map +1 -1
- package/dist/src/services/site.d.ts +20 -0
- package/dist/src/services/site.d.ts.map +1 -1
- package/dist/src/services/site.js +70 -0
- package/dist/src/services/site.js.map +1 -1
- package/dist/src/storage/interface.d.ts +48 -0
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/interface.js.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +11 -1
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +128 -2
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +7 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +27 -2
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/direct-message.d.ts +5 -1
- package/dist/src/storage/providers/sqlite/repos/direct-message.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/direct-message.js +48 -0
- package/dist/src/storage/providers/sqlite/repos/direct-message.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts +2 -0
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.js +55 -0
- package/dist/src/storage/providers/sqlite/repos/memory.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +61 -0
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/direct-message.repository.d.ts +5 -1
- package/dist/src/storage/repositories/direct-message.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/memory.repository.d.ts +25 -0
- package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
- package/dist/src/utils/node-descriptor.d.ts +34 -0
- package/dist/src/utils/node-descriptor.d.ts.map +1 -0
- package/dist/src/utils/node-descriptor.js +42 -0
- package/dist/src/utils/node-descriptor.js.map +1 -0
- package/dist/src/utils/version.d.ts +3 -0
- package/dist/src/utils/version.d.ts.map +1 -0
- package/dist/src/utils/version.js +40 -0
- package/dist/src/utils/version.js.map +1 -0
- package/dist/static/app-catalog.html +643 -4
- package/package.json +5 -2
- package/prisma/schema.postgres.prisma +51 -18
- package/prisma/schema.prisma +29 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file notebook.css
|
|
3
|
+
* @description Styles for the profile Notebook tab (pf-nb-* prefix): capture box, librarian hits,
|
|
4
|
+
* and inbox notes. Dark-theme only — all colors/spacing via theme.css variables.
|
|
5
|
+
* @version-history
|
|
6
|
+
* v1.0.0 — 2026-06-19 — Initial: capture + librarian + inbox (slice A).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
.pf-nb-capture {
|
|
10
|
+
margin-bottom: var(--space-lg, 1.5rem);
|
|
11
|
+
}
|
|
12
|
+
.pf-nb-textarea {
|
|
13
|
+
width: 100%;
|
|
14
|
+
resize: vertical;
|
|
15
|
+
min-height: 5rem;
|
|
16
|
+
font-family: inherit;
|
|
17
|
+
}
|
|
18
|
+
.pf-nb-capture-actions {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: var(--space-sm, 0.75rem);
|
|
22
|
+
margin-top: var(--space-sm, 0.75rem);
|
|
23
|
+
flex-wrap: wrap;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.pf-nb-section {
|
|
27
|
+
margin-top: var(--space-lg, 1.5rem);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.pf-nb-search {
|
|
31
|
+
flex: 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.pf-nb-scope { margin-bottom: var(--space-sm, 0.75rem); }
|
|
35
|
+
.pf-nb-hit-producer {
|
|
36
|
+
margin-top: var(--space-xs, 0.4rem);
|
|
37
|
+
color: var(--text-dim, var(--text));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.pf-nb-hits {
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
gap: var(--space-sm, 0.75rem);
|
|
44
|
+
}
|
|
45
|
+
.pf-nb-hit {
|
|
46
|
+
background: var(--card);
|
|
47
|
+
border: 1px solid var(--border);
|
|
48
|
+
border-radius: var(--radius, 8px);
|
|
49
|
+
padding: var(--space-sm, 0.75rem) var(--space-md, 1rem);
|
|
50
|
+
}
|
|
51
|
+
.pf-nb-hit-head {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
justify-content: space-between;
|
|
55
|
+
gap: var(--space-sm, 0.75rem);
|
|
56
|
+
}
|
|
57
|
+
.pf-nb-hit-title {
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
color: var(--text);
|
|
60
|
+
}
|
|
61
|
+
.pf-nb-hit-snippet {
|
|
62
|
+
margin-top: var(--space-xs, 0.4rem);
|
|
63
|
+
color: var(--text-dim, var(--text));
|
|
64
|
+
font-size: 0.9em;
|
|
65
|
+
line-height: 1.4;
|
|
66
|
+
}
|
|
67
|
+
.pf-nb-hit-foot {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
gap: var(--space-sm, 0.75rem);
|
|
72
|
+
margin-top: var(--space-xs, 0.4rem);
|
|
73
|
+
}
|
|
74
|
+
.pf-nb-hit-key {
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
text-overflow: ellipsis;
|
|
77
|
+
white-space: nowrap;
|
|
78
|
+
font-family: var(--font-mono, monospace);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.pf-nb-inbox {
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-direction: column;
|
|
84
|
+
gap: var(--space-sm, 0.75rem);
|
|
85
|
+
}
|
|
86
|
+
.pf-nb-note {
|
|
87
|
+
background: var(--bg-dim, var(--card));
|
|
88
|
+
border: 1px solid var(--border);
|
|
89
|
+
border-radius: var(--radius, 8px);
|
|
90
|
+
padding: var(--space-sm, 0.75rem) var(--space-md, 1rem);
|
|
91
|
+
}
|
|
92
|
+
.pf-nb-note-text {
|
|
93
|
+
color: var(--text);
|
|
94
|
+
word-break: break-word;
|
|
95
|
+
}
|
|
96
|
+
.pf-nb-note-line {
|
|
97
|
+
display: block;
|
|
98
|
+
white-space: nowrap;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
text-overflow: ellipsis;
|
|
101
|
+
color: var(--text-dim, var(--text));
|
|
102
|
+
}
|
|
103
|
+
.pf-nb-note-text--peek {
|
|
104
|
+
max-height: 9rem;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
position: relative;
|
|
107
|
+
}
|
|
108
|
+
.pf-nb-note-text--peek::after {
|
|
109
|
+
content: '';
|
|
110
|
+
position: absolute;
|
|
111
|
+
left: 0;
|
|
112
|
+
right: 0;
|
|
113
|
+
bottom: 0;
|
|
114
|
+
height: 2.5rem;
|
|
115
|
+
background: linear-gradient(transparent, var(--bg-dim, var(--card)));
|
|
116
|
+
pointer-events: none;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.pf-nb-inbox-bar { margin-bottom: var(--space-sm, 0.75rem); }
|
|
120
|
+
.pf-nb-sort { max-width: 12rem; }
|
|
121
|
+
.pf-nb-note-meta {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: var(--space-xs, 0.4rem);
|
|
125
|
+
}
|
|
126
|
+
.pf-nb-view-btn {
|
|
127
|
+
padding: 0.05rem 0.45rem;
|
|
128
|
+
line-height: 1.2;
|
|
129
|
+
}
|
|
130
|
+
.pf-nb-note-foot {
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
justify-content: space-between;
|
|
134
|
+
gap: var(--space-sm, 0.75rem);
|
|
135
|
+
margin-top: var(--space-xs, 0.4rem);
|
|
136
|
+
}
|
|
137
|
+
.pf-nb-note-btns {
|
|
138
|
+
display: flex;
|
|
139
|
+
gap: var(--space-xs, 0.4rem);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.pf-nb-suggest {
|
|
143
|
+
margin-top: var(--space-sm, 0.75rem);
|
|
144
|
+
padding: var(--space-md, 1rem);
|
|
145
|
+
background: var(--surface, var(--card));
|
|
146
|
+
border: 1px solid var(--border);
|
|
147
|
+
border-radius: var(--radius, 8px);
|
|
148
|
+
display: flex;
|
|
149
|
+
flex-direction: column;
|
|
150
|
+
gap: var(--space-xs, 0.4rem);
|
|
151
|
+
}
|
|
152
|
+
.pf-nb-suggest-reason {
|
|
153
|
+
font-style: italic;
|
|
154
|
+
margin-bottom: var(--space-xs, 0.4rem);
|
|
155
|
+
}
|
|
156
|
+
.pf-nb-suggest-label {
|
|
157
|
+
font-size: 0.8em;
|
|
158
|
+
color: var(--text-dim, var(--text));
|
|
159
|
+
margin-top: var(--space-xs, 0.4rem);
|
|
160
|
+
}
|
|
161
|
+
.pf-nb-suggest-body {
|
|
162
|
+
width: 100%;
|
|
163
|
+
resize: vertical;
|
|
164
|
+
font-family: inherit;
|
|
165
|
+
}
|
|
166
|
+
.pf-nb-suggest-alts {
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-wrap: wrap;
|
|
169
|
+
align-items: center;
|
|
170
|
+
gap: var(--space-xs, 0.4rem);
|
|
171
|
+
margin-top: var(--space-xs, 0.4rem);
|
|
172
|
+
}
|
|
173
|
+
.pf-nb-suggest-actions {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: var(--space-sm, 0.75rem);
|
|
177
|
+
margin-top: var(--space-sm, 0.75rem);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.pf-nb-progress { gap: var(--space-sm, 0.75rem); }
|
|
181
|
+
.pf-nb-steps {
|
|
182
|
+
list-style: none;
|
|
183
|
+
margin: 0;
|
|
184
|
+
padding: 0;
|
|
185
|
+
display: flex;
|
|
186
|
+
flex-direction: column;
|
|
187
|
+
gap: 0.2rem;
|
|
188
|
+
}
|
|
189
|
+
.pf-nb-step {
|
|
190
|
+
font-size: 0.85em;
|
|
191
|
+
color: var(--text-dim, var(--text));
|
|
192
|
+
opacity: 0.6;
|
|
193
|
+
}
|
|
194
|
+
.pf-nb-step.active { opacity: 1; color: var(--text); font-weight: 600; }
|
|
195
|
+
.pf-nb-step.done { opacity: 0.85; color: var(--success, var(--text)); }
|
|
@@ -2427,6 +2427,8 @@
|
|
|
2427
2427
|
.pj-doc-imgbar { margin: 0.3rem 0; display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; }
|
|
2428
2428
|
.pj-file-btn { cursor: pointer; }
|
|
2429
2429
|
.pj-file-btn input { display: none; }
|
|
2430
|
+
/* Visually-hidden file input (organism / workspace ZIP import) — replaces inline style="display:none". */
|
|
2431
|
+
.pj-hidden-input { display: none; }
|
|
2430
2432
|
.pj-file-btn-icon { margin-right: 0.15rem; }
|
|
2431
2433
|
.pj-imgbar-hint { font-size: 0.78rem; color: var(--muted); }
|
|
2432
2434
|
.pj-img-vis { margin: 0.2rem 0 0.5rem; padding: 0.55rem 0.65rem; border: 1px solid var(--border); border-radius: 8px; background: var(--card); }
|
|
@@ -2942,3 +2944,16 @@
|
|
|
2942
2944
|
.pf-eco-tech-section-title { font-weight: 700; font-size: .82rem; margin-bottom: .4rem; color: var(--text-dim); }
|
|
2943
2945
|
.pf-eco-tech-principal { display: inline-block; background: var(--card); border: 1px solid var(--border); border-radius: 6px; padding: .3rem .5rem; word-break: break-all; }
|
|
2944
2946
|
.pf-eco-tech-access { margin: -.15rem 0 .4rem; }
|
|
2947
|
+
|
|
2948
|
+
/* ── Presence control (Koti home) — backed by PresenceControl in landing-page.js.
|
|
2949
|
+
Self-contained card; previews the same <PresenceDot> shown next to people. ── */
|
|
2950
|
+
.pf-presence-card { border: 1px solid var(--border); border-radius: 12px; background: var(--card); padding: 1rem 1.1rem; margin-bottom: 1rem; }
|
|
2951
|
+
.pf-presence-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
|
|
2952
|
+
.pf-presence-head .section-desc { margin-bottom: .75rem; }
|
|
2953
|
+
.pf-presence-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin: .5rem 0; }
|
|
2954
|
+
.pf-presence-label { font-size: .85rem; font-weight: 600; color: var(--text-dim); }
|
|
2955
|
+
.pf-presence-modes { display: inline-flex; gap: .4rem; }
|
|
2956
|
+
.pf-presence-pill { border: 1px solid var(--border); background: var(--bg-dim); color: var(--text); border-radius: 999px; padding: .3rem .85rem; font-size: .82rem; cursor: pointer; }
|
|
2957
|
+
.pf-presence-pill--on { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
2958
|
+
.pf-presence-pill:disabled { opacity: .6; cursor: default; }
|
|
2959
|
+
.pf-presence-hint { font-size: .78rem; color: var(--text-dim); margin: .15rem 0 .35rem; }
|
package/dist/public/js/api.js
CHANGED
|
@@ -123,7 +123,9 @@ export function apiPatch(path, body) {
|
|
|
123
123
|
return api(path, { method: 'PATCH', body: JSON.stringify(body) });
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
/** DELETE shorthand. */
|
|
127
|
-
export function apiDelete(path) {
|
|
128
|
-
return api(path,
|
|
126
|
+
/** DELETE shorthand. Forwards an optional request body (e.g. `{ target }`). */
|
|
127
|
+
export function apiDelete(path, body) {
|
|
128
|
+
return api(path, body === undefined
|
|
129
|
+
? { method: 'DELETE' }
|
|
130
|
+
: { method: 'DELETE', body: JSON.stringify(body) });
|
|
129
131
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* html`<${AuthImage} src="/v1/memory/files/foo.png" class="file-thumb" alt="foo" />`
|
|
8
8
|
* @version-history
|
|
9
9
|
* v1.0.0 — 2026-03-17 — Initial implementation
|
|
10
|
+
* v1.0.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
10
11
|
*/
|
|
11
12
|
import { h } from 'preact';
|
|
12
13
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
@@ -21,7 +22,7 @@ export default function AuthImage({ src, alt, ...props }) {
|
|
|
21
22
|
if (!src) return;
|
|
22
23
|
|
|
23
24
|
let cancelled = false;
|
|
24
|
-
const headers = {};
|
|
25
|
+
const headers = /** @type {Record<string,string>} */ ({});
|
|
25
26
|
|
|
26
27
|
if (window.AIMEAT?.auth?.hasSession) {
|
|
27
28
|
const session = window.AIMEAT.auth.getSession();
|
|
@@ -32,7 +33,7 @@ export default function AuthImage({ src, alt, ...props }) {
|
|
|
32
33
|
|
|
33
34
|
fetch(src, { headers })
|
|
34
35
|
.then(r => {
|
|
35
|
-
if (!r.ok) throw new Error(r.status);
|
|
36
|
+
if (!r.ok) throw new Error(String(r.status));
|
|
36
37
|
return r.blob();
|
|
37
38
|
})
|
|
38
39
|
.then(blob => {
|
|
@@ -12,7 +12,7 @@ import { t } from '/js/i18n.js';
|
|
|
12
12
|
* @param {Set<string>} props.selected — currently active filter tags
|
|
13
13
|
* @param {(tag: string) => void} props.onToggle — called when a tag is clicked
|
|
14
14
|
* @param {() => void} props.onClear — called when clear button is clicked
|
|
15
|
-
* @param {number} [props.limit]
|
|
15
|
+
* @param {number} [props.limit] - show only the first N tags behind a "show all" toggle.
|
|
16
16
|
* Selected tags always stay visible so an active filter can't hide its own pill.
|
|
17
17
|
*/
|
|
18
18
|
export default function TagCloud({ tags, selected, onToggle, onClear, limit }) {
|
|
@@ -9,7 +9,7 @@ import { t } from '/js/i18n.js';
|
|
|
9
9
|
* @param {Object} props
|
|
10
10
|
* @param {string[]} props.tags — current tags on the item
|
|
11
11
|
* @param {(tags: string[]) => void} props.onSave — called with updated tag array on add/remove
|
|
12
|
-
* @param {number} [props.maxTags=20]
|
|
12
|
+
* @param {number} [props.maxTags=20] - maximum tags allowed
|
|
13
13
|
*/
|
|
14
14
|
export default function TagEditor({ tags, onSave, maxTags = 20 }) {
|
|
15
15
|
const [input, setInput] = useState('');
|
package/dist/public/js/hooks.js
CHANGED
|
@@ -52,8 +52,7 @@ export function useApiCall(endpoint, options = {}) {
|
|
|
52
52
|
if (!cancelled) setLoading(false);
|
|
53
53
|
});
|
|
54
54
|
return () => { cancelled = true; };
|
|
55
|
-
// deps are intentionally dynamic
|
|
56
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
|
+
// deps are intentionally dynamic (endpoint/method/reloadKey + caller-supplied deps)
|
|
57
56
|
}, [endpoint, method, reloadKey, ...deps]);
|
|
58
57
|
|
|
59
58
|
/** Call reload() to re-trigger the fetch (e.g. after a mutation). */
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file presence-store.js
|
|
3
|
+
* @description Shared client-side presence store powering the `usePresence(ghii)`
|
|
4
|
+
* hook. Every <PresenceDot> in a list subscribes here; the store COALESCES all
|
|
5
|
+
* ghiis requested within one tick into a single batched GET /v1/presence call —
|
|
6
|
+
* so a 50-row member list makes one request, not fifty. Results are cached with
|
|
7
|
+
* a short TTL and re-fetched on the global `aimeat-live-update` SSE event, so all
|
|
8
|
+
* dots flip live without per-component polling.
|
|
9
|
+
* @structure
|
|
10
|
+
* - usePresence(ghii) — preact hook → { status, since } | undefined
|
|
11
|
+
* - refreshAll() — invalidate + re-batch all currently-subscribed ghiis
|
|
12
|
+
* - internal: cache, subscriber registry, pending-batch flusher
|
|
13
|
+
* @usage import { usePresence } from '/js/presence-store.js';
|
|
14
|
+
* @version-history
|
|
15
|
+
* v1.0.0 — 2026-06-19 — Initial shared presence store (cache + batch + live refresh).
|
|
16
|
+
*/
|
|
17
|
+
import { useState, useEffect } from 'preact/hooks';
|
|
18
|
+
import { getPresenceBatch } from '/js/services/presence.js';
|
|
19
|
+
|
|
20
|
+
const cache = new Map(); // ghii → { status, since }
|
|
21
|
+
const subs = new Map(); // ghii → Set<fn>
|
|
22
|
+
const lastFetched = new Map(); // ghii → ms
|
|
23
|
+
let pending = new Set();
|
|
24
|
+
let timer = null;
|
|
25
|
+
let liveBound = false;
|
|
26
|
+
|
|
27
|
+
const TTL_MS = 60_000;
|
|
28
|
+
const BATCH_DELAY_MS = 40;
|
|
29
|
+
|
|
30
|
+
function notify(ghii) {
|
|
31
|
+
const set = subs.get(ghii);
|
|
32
|
+
if (set) for (const fn of set) fn(cache.get(ghii));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function flush() {
|
|
36
|
+
timer = null;
|
|
37
|
+
const ids = [...pending];
|
|
38
|
+
pending = new Set();
|
|
39
|
+
if (!ids.length) return;
|
|
40
|
+
try {
|
|
41
|
+
const map = await getPresenceBatch(ids);
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
for (const ghii of ids) {
|
|
44
|
+
cache.set(ghii, map[ghii] || { status: 'unknown', since: null });
|
|
45
|
+
lastFetched.set(ghii, now);
|
|
46
|
+
notify(ghii);
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
/* leave the cache as-is; a later live-update or remount retries */
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function schedule() {
|
|
54
|
+
if (!timer) timer = setTimeout(flush, BATCH_DELAY_MS);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function request(ghii, force) {
|
|
58
|
+
if (!force && lastFetched.has(ghii) && Date.now() - lastFetched.get(ghii) < TTL_MS) return;
|
|
59
|
+
pending.add(ghii);
|
|
60
|
+
schedule();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Invalidate and re-fetch every currently-subscribed identity (called on SSE updates). */
|
|
64
|
+
export function refreshAll() {
|
|
65
|
+
lastFetched.clear();
|
|
66
|
+
for (const ghii of subs.keys()) pending.add(ghii);
|
|
67
|
+
if (pending.size) schedule();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function bindLive() {
|
|
71
|
+
if (liveBound) return;
|
|
72
|
+
liveBound = true;
|
|
73
|
+
window.addEventListener('aimeat-live-update', refreshAll);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to a single identity's presence. Returns { status, since } (or
|
|
78
|
+
* undefined until the first fetch resolves). Pass a falsy ghii to opt out.
|
|
79
|
+
*/
|
|
80
|
+
export function usePresence(ghii) {
|
|
81
|
+
const [val, setVal] = useState(() => (ghii ? cache.get(ghii) : undefined));
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (!ghii) { setVal(undefined); return; }
|
|
84
|
+
bindLive();
|
|
85
|
+
let set = subs.get(ghii);
|
|
86
|
+
if (!set) { set = new Set(); subs.set(ghii, set); }
|
|
87
|
+
const fn = (v) => setVal(v);
|
|
88
|
+
set.add(fn);
|
|
89
|
+
setVal(cache.get(ghii));
|
|
90
|
+
request(ghii);
|
|
91
|
+
return () => {
|
|
92
|
+
set.delete(fn);
|
|
93
|
+
if (!set.size) subs.delete(ghii);
|
|
94
|
+
};
|
|
95
|
+
}, [ghii]);
|
|
96
|
+
return val;
|
|
97
|
+
}
|
|
@@ -38,6 +38,9 @@ export const patchBoardMembers = (id, body) => apiPatch(`/v1/boards/${encodeURIC
|
|
|
38
38
|
// ── Work ──
|
|
39
39
|
export const getAdminWork = () => apiGet('/v1/admin/work');
|
|
40
40
|
|
|
41
|
+
// ── Direct-message delivery telemetry ──
|
|
42
|
+
export const getMessageStats = () => apiGet('/v1/admin/messages/stats');
|
|
43
|
+
|
|
41
44
|
// ── Maintenance ──
|
|
42
45
|
export const getMaintenance = () => apiGet('/v1/admin/maintenance');
|
|
43
46
|
export const setMaintenance = (enabled, message) => apiPost('/v1/admin/maintenance', { enabled, message });
|
|
@@ -62,6 +65,10 @@ export const removePeer = (nodeId) => apiDelete(`/v1/federation/peers/${encodeUR
|
|
|
62
65
|
export const removePeerEmergency = (nodeId) => apiDelete(`/v1/federation/peers/${encodeURIComponent(nodeId)}?emergency=true`);
|
|
63
66
|
export const testFederationNode = (targetUrl) => apiPost('/v1/federation/test', { target_url: targetUrl });
|
|
64
67
|
export const updatePeerPolicy = (nodeId, policy) => apiPut(`/v1/federation/peers/${encodeURIComponent(nodeId)}`, policy);
|
|
68
|
+
export const promotePeer = (nodeId, opts = {}) => apiPost(`/v1/federation/peers/${encodeURIComponent(nodeId)}/promote`, opts);
|
|
69
|
+
export const getFederationBook = () => apiGet('/v1/federation/book');
|
|
70
|
+
export const rebuildFederationBook = () => apiPost('/v1/federation/book/rebuild', {});
|
|
71
|
+
export const pullFederationBook = () => apiPost('/v1/federation/book/pull', {});
|
|
65
72
|
export const joinGenesisNetwork = (genesisUrl, role) => apiPost('/v1/admin/federation/join', { genesis_url: genesisUrl, role: role || 'contributor' });
|
|
66
73
|
|
|
67
74
|
// ── Hooks ──
|
|
@@ -162,6 +169,8 @@ export const importSiteBundle = (bundle) => apiPost('/v1/site/import', bundle);
|
|
|
162
169
|
export const clearSiteCache = () => apiPost('/v1/site/cache-invalidate');
|
|
163
170
|
export const getSitePrompt = () => apiGet('/v1/site/prompt');
|
|
164
171
|
export const triggerLbSync = () => apiPost('/v1/admin/site/sync');
|
|
172
|
+
export const getHeaderNav = () => apiGet('/v1/site/header-nav');
|
|
173
|
+
export const saveHeaderNav = (order, hidden) => apiPut('/v1/site/header-nav', { order, hidden });
|
|
165
174
|
|
|
166
175
|
// ── Memory (for portal memory keys) ──
|
|
167
176
|
export const addMemory = (key, value) => apiPost('/v1/memory', { key, value, visibility: 'private' });
|
|
@@ -269,9 +278,9 @@ export const getAdminAgentTasks = (params = {}) => {
|
|
|
269
278
|
|
|
270
279
|
// ── Sharing Groups (admin) ──
|
|
271
280
|
export const getAdminSharingGroups = () => apiGet('/v1/admin/sharing-groups');
|
|
272
|
-
|
|
273
|
-
// ── Subdomain mappings (operator) ──
|
|
274
|
-
export const getSubdomainSites = () => apiGet('/v1/admin/subdomains');
|
|
275
|
-
export const createSubdomainSite = (body) => apiPost('/v1/admin/subdomains', body);
|
|
276
|
-
export const updateSubdomainSite = (sub, updates) => apiPatch(`/v1/admin/subdomains/${encodeURIComponent(sub)}`, updates);
|
|
281
|
+
|
|
282
|
+
// ── Subdomain mappings (operator) ──
|
|
283
|
+
export const getSubdomainSites = () => apiGet('/v1/admin/subdomains');
|
|
284
|
+
export const createSubdomainSite = (body) => apiPost('/v1/admin/subdomains', body);
|
|
285
|
+
export const updateSubdomainSite = (sub, updates) => apiPatch(`/v1/admin/subdomains/${encodeURIComponent(sub)}`, updates);
|
|
277
286
|
export const deleteSubdomainSite = (sub) => apiDelete(`/v1/admin/subdomains/${encodeURIComponent(sub)}`);
|
|
@@ -66,7 +66,7 @@ export async function deletePost(boardId, postId) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/** Update board members (add/remove GAIIs). */
|
|
69
|
-
export async function updateBoardMembers(boardId, { add, remove }) {
|
|
69
|
+
export async function updateBoardMembers(boardId, { add, remove } = /** @type {{ add?: any, remove?: any }} */ ({})) {
|
|
70
70
|
return api(`/v1/boards/${encodeURIComponent(boardId)}/members`, {
|
|
71
71
|
method: 'PATCH',
|
|
72
72
|
body: JSON.stringify({ add, remove }),
|
|
@@ -41,7 +41,7 @@ export async function listPending() {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/** Approve or deny a pending request by its user code, selecting scopes (and optional data areas). */
|
|
44
|
-
export async function approve(userCode, { action, scopes, data_areas } = {}) {
|
|
44
|
+
export async function approve(userCode, { action, scopes, data_areas } = /** @type {{ action?: string, scopes?: any, data_areas?: any }} */ ({})) {
|
|
45
45
|
return apiPost(`/v1/ecosystem-apps/${encodeURIComponent(userCode)}/approve`, { action, scopes, data_areas });
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -27,7 +27,7 @@ Available building blocks:
|
|
|
27
27
|
- Cortex: Client-side JS domain library (IIFE on AIMEAT namespace). Wraps extension APIs and memory reads into clean domain methods for apps.
|
|
28
28
|
|
|
29
29
|
Extensions run in an ISOLATED V8 sandbox with ONLY this API (no Node.js, no global fetch, no setTimeout, no require, no import):
|
|
30
|
-
ctx.memory.get(key) → value or null (ALWAYS null-check before using:
|
|
30
|
+
ctx.memory.get(key) → value or null (ALWAYS null-check before using: \`|| []\` or \`|| {}\`)
|
|
31
31
|
ctx.memory.set(key, value) → void
|
|
32
32
|
ctx.memory.search(prefix) → Array<{ key, value }> (NOT plain strings!)
|
|
33
33
|
ctx.memory.delete(key) → boolean
|
|
@@ -1481,7 +1481,7 @@ export function summarizeExtensionApi(result) {
|
|
|
1481
1481
|
: '';
|
|
1482
1482
|
|
|
1483
1483
|
if (actionsSection) {
|
|
1484
|
-
const actionBlocks = actionsSection.split(/\n
|
|
1484
|
+
const actionBlocks = actionsSection.split(/\n {2}- id:/);
|
|
1485
1485
|
for (const block of actionBlocks.slice(1)) {
|
|
1486
1486
|
const id = block.split('\n')[0].trim();
|
|
1487
1487
|
const desc = block.match(/description:\s*"([^"]+)"/)?.[1] || '';
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* const result = await smokeTest('extension', 'prh-tiedonhaku', session);
|
|
8
8
|
* @version-history
|
|
9
9
|
* v1.0.0 — 2026-03-26 — Initial smoke test module
|
|
10
|
+
* v1.0.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
import { apiPost, apiGet } from '/js/api.js';
|
|
@@ -16,7 +17,7 @@ import { apiPost, apiGet } from '/js/api.js';
|
|
|
16
17
|
* @param {string} type - Component type: 'extension', 'cortex', 'app'
|
|
17
18
|
* @param {string} registeredAs - The registered name of the component
|
|
18
19
|
* @param {object} session - Auth session for API calls
|
|
19
|
-
* @returns {{ passed: boolean, error: string|null }}
|
|
20
|
+
* @returns {Promise<{ passed: boolean, error: string|null }>}
|
|
20
21
|
*/
|
|
21
22
|
export async function smokeTest(type, registeredAs, session) {
|
|
22
23
|
try {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
* v5.0.0 — 2026-03-26 — Add validateSkeleton with cross-check against interview
|
|
48
48
|
* sampleResponse; add validateUnit with anti-pattern scan; add crossCheckSampleData,
|
|
49
49
|
* extractOutputFieldsNearUrl, deepFieldExists helpers
|
|
50
|
+
* v5.0.1 — 2026-06-19 — lint fixes (misleading-char-class/unused-expression/empty-block)
|
|
50
51
|
*/
|
|
51
52
|
import { parse as parseYaml, stringify as stringifyYaml } from '/lib/yaml.mjs';
|
|
52
53
|
|
|
@@ -66,7 +67,7 @@ function sanitizeJson(text) {
|
|
|
66
67
|
// Strip markdown backslash escaping: \[ \] \{ \} \( \) \* \_ \` \| \~ \#
|
|
67
68
|
s = s.replace(/\\([[\]{}()*_`|~#])/g, '$1');
|
|
68
69
|
s = s.replace(/,\s*([}\]])/g, '$1');
|
|
69
|
-
s = s.replace(
|
|
70
|
+
s = s.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
|
|
70
71
|
return s;
|
|
71
72
|
}
|
|
72
73
|
|
|
@@ -84,7 +85,7 @@ function preCleanYaml(text) {
|
|
|
84
85
|
s = s.replace(/\\\[/g, '[').replace(/\\\]/g, ']');
|
|
85
86
|
s = s.replace(/\\\{/g, '{').replace(/\\\}/g, '}');
|
|
86
87
|
// Remove zero-width unicode
|
|
87
|
-
s = s.replace(
|
|
88
|
+
s = s.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
|
|
88
89
|
// Fix common AI mistake: action list items missing "id:" key
|
|
89
90
|
// e.g. " - refreshQuotes\n description:" → " - id: refreshQuotes\n description:"
|
|
90
91
|
// Only match lines under "actions:" where the list item is a bare word followed by description on next line
|
|
@@ -889,11 +890,8 @@ export function validateBlueprint(result) {
|
|
|
889
890
|
}
|
|
890
891
|
}
|
|
891
892
|
|
|
892
|
-
//
|
|
893
|
-
|
|
894
|
-
if (parsed.testScenarios) parsed.testScenarios = parsed.testScenarios;
|
|
895
|
-
if (parsed.architecture) parsed.architecture = parsed.architecture;
|
|
896
|
-
|
|
893
|
+
// New top-level blueprint fields (settings/testScenarios/architecture) are preserved
|
|
894
|
+
// automatically — `parsed` is returned in full below.
|
|
897
895
|
return { valid: errors.length === 0, errors, warnings, parsed, extracted: json };
|
|
898
896
|
} catch (e) {
|
|
899
897
|
errors.push(`Invalid JSON: ${e.message}`);
|
|
@@ -1022,7 +1020,7 @@ function extractOutputFieldsNearUrl(yaml, url) {
|
|
|
1022
1020
|
}
|
|
1023
1021
|
}
|
|
1024
1022
|
// Stop at the next action/method
|
|
1025
|
-
if (nearUrl && inOutput && /^
|
|
1023
|
+
if (nearUrl && inOutput && /^ {2}- id:|^ {2}- name:|^\w/.test(line) && !line.includes(url)) {
|
|
1026
1024
|
break;
|
|
1027
1025
|
}
|
|
1028
1026
|
}
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
* v6.0.0 — 2026-03-26 — Add multi-pass data model: PASS_TYPES, MULTI_PASS_TYPES,
|
|
41
41
|
* createInitialPasses, createUnitPasses, extractUnitsFromSkeleton, getNextPass,
|
|
42
42
|
* isDuplicatePrescription; skeleton/unit/test/reflection storage functions
|
|
43
|
+
* v6.0.1 — 2026-06-19 — lint fixes (misleading-char-class/unused-expression/empty-block)
|
|
43
44
|
*/
|
|
44
45
|
import { apiGet, apiPost, apiPut, apiDelete } from '/js/api.js';
|
|
45
46
|
import { parse as parseYaml, stringify as stringifyYaml } from '/lib/yaml.mjs';
|
|
@@ -716,7 +717,7 @@ function cleanYaml(text) {
|
|
|
716
717
|
s = s.replace(/\\_/g, '_');
|
|
717
718
|
s = s.replace(/\\\[/g, '[').replace(/\\\]/g, ']');
|
|
718
719
|
s = s.replace(/\\\{/g, '{').replace(/\\\}/g, '}');
|
|
719
|
-
s = s.replace(
|
|
720
|
+
s = s.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
|
|
720
721
|
try {
|
|
721
722
|
const parsed = parseYaml(s);
|
|
722
723
|
return stringifyYaml(parsed, { lineWidth: 0 });
|
|
@@ -1050,8 +1051,8 @@ export async function removeComponents(projectId, componentIds, includeMemory, s
|
|
|
1050
1051
|
const locale = name.replace(/^.*i18n-/, '');
|
|
1051
1052
|
if (locale) {
|
|
1052
1053
|
// Find service slug from sibling extension/csm
|
|
1053
|
-
const extSibling =
|
|
1054
|
-
const csmSibling =
|
|
1054
|
+
const extSibling = components.find(c => c.type === 'extension' && c.registeredAs);
|
|
1055
|
+
const csmSibling = components.find(c => c.type === 'csm' && c.registeredAs);
|
|
1055
1056
|
const svcSlug = extSibling?.registeredAs || csmSibling?.registeredAs?.split('/')?.pop() || '';
|
|
1056
1057
|
const memKey = svcSlug ? `${svcSlug}.i18n.${locale}` : `i18n.${locale}`;
|
|
1057
1058
|
try { await apiDelete(`/v1/memory/${encodeURIComponent(memKey)}`); } catch { /* best effort */ }
|
|
@@ -28,7 +28,7 @@ Available building blocks:
|
|
|
28
28
|
- Cortex: Client-side JS domain library (IIFE on AIMEAT namespace). Wraps extension APIs and memory reads into clean domain methods for apps.
|
|
29
29
|
|
|
30
30
|
Extensions run in an ISOLATED V8 sandbox with ONLY this API (no Node.js, no global fetch, no setTimeout, no require, no import):
|
|
31
|
-
ctx.memory.get(key) → value or null (ALWAYS null-check before using:
|
|
31
|
+
ctx.memory.get(key) → value or null (ALWAYS null-check before using: \`|| []\` or \`|| {}\`)
|
|
32
32
|
ctx.memory.set(key, value) → void
|
|
33
33
|
ctx.memory.search(prefix) → Array<{ key, value }> (NOT plain strings!)
|
|
34
34
|
ctx.memory.delete(key) → boolean
|
|
@@ -1483,7 +1483,7 @@ export function summarizeExtensionApi(result) {
|
|
|
1483
1483
|
: '';
|
|
1484
1484
|
|
|
1485
1485
|
if (actionsSection) {
|
|
1486
|
-
const actionBlocks = actionsSection.split(/\n
|
|
1486
|
+
const actionBlocks = actionsSection.split(/\n {2}- id:/);
|
|
1487
1487
|
for (const block of actionBlocks.slice(1)) {
|
|
1488
1488
|
const id = block.split('\n')[0].trim();
|
|
1489
1489
|
const desc = block.match(/description:\s*"([^"]+)"/)?.[1] || '';
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* const result = await smokeTest('extension', 'prh-tiedonhaku', session);
|
|
8
8
|
* @version-history
|
|
9
9
|
* v1.0.0 — 2026-03-26 — Initial smoke test module
|
|
10
|
+
* v1.0.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
import { apiPost, apiGet } from '/js/api.js';
|
|
@@ -16,7 +17,7 @@ import { apiPost, apiGet } from '/js/api.js';
|
|
|
16
17
|
* @param {string} type - Component type: 'extension', 'cortex', 'app'
|
|
17
18
|
* @param {string} registeredAs - The registered name of the component
|
|
18
19
|
* @param {object} session - Auth session for API calls
|
|
19
|
-
* @returns {{ passed: boolean, error: string|null }}
|
|
20
|
+
* @returns {Promise<{ passed: boolean, error: string|null }>}
|
|
20
21
|
*/
|
|
21
22
|
export async function smokeTest(type, registeredAs, session) {
|
|
22
23
|
try {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
* v4.5.0 — 2026-03-16 — Cortex validator supports single-block format (YAML + JS
|
|
45
45
|
* separated by // lib/ comment) in addition to legacy separate blocks. Accept
|
|
46
46
|
* var/let/const for LIB_NAME declaration.
|
|
47
|
+
* v4.5.1 — 2026-06-19 — lint fixes (misleading-char-class/unused-expression/empty-block)
|
|
47
48
|
*/
|
|
48
49
|
import { parse as parseYaml, stringify as stringifyYaml } from '../../lib/yaml.mjs';
|
|
49
50
|
|
|
@@ -63,7 +64,7 @@ function sanitizeJson(text) {
|
|
|
63
64
|
// Strip markdown backslash escaping: \[ \] \{ \} \( \) \* \_ \` \| \~ \#
|
|
64
65
|
s = s.replace(/\\([[\]{}()*_`|~#])/g, '$1');
|
|
65
66
|
s = s.replace(/,\s*([}\]])/g, '$1');
|
|
66
|
-
s = s.replace(
|
|
67
|
+
s = s.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
|
|
67
68
|
return s;
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -81,7 +82,7 @@ function preCleanYaml(text) {
|
|
|
81
82
|
s = s.replace(/\\\[/g, '[').replace(/\\\]/g, ']');
|
|
82
83
|
s = s.replace(/\\\{/g, '{').replace(/\\\}/g, '}');
|
|
83
84
|
// Remove zero-width unicode
|
|
84
|
-
s = s.replace(
|
|
85
|
+
s = s.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
|
|
85
86
|
// Fix common AI mistake: action list items missing "id:" key
|
|
86
87
|
// e.g. " - refreshQuotes\n description:" → " - id: refreshQuotes\n description:"
|
|
87
88
|
// Only match lines under "actions:" where the list item is a bare word followed by description on next line
|
|
@@ -895,11 +896,8 @@ export function validateBlueprint(result) {
|
|
|
895
896
|
}
|
|
896
897
|
}
|
|
897
898
|
|
|
898
|
-
//
|
|
899
|
-
|
|
900
|
-
if (parsed.testScenarios) parsed.testScenarios = parsed.testScenarios;
|
|
901
|
-
if (parsed.architecture) parsed.architecture = parsed.architecture;
|
|
902
|
-
|
|
899
|
+
// New top-level blueprint fields (settings/testScenarios/architecture) are preserved
|
|
900
|
+
// automatically — `parsed` is returned in full below.
|
|
903
901
|
return { valid: errors.length === 0, errors, warnings, parsed, extracted: json };
|
|
904
902
|
} catch (e) {
|
|
905
903
|
errors.push(`Invalid JSON: ${e.message}`);
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
* v4.5.0 — 2026-03-19 — Add writeProjectLog for user-action activity logging; fix apiPatch import
|
|
38
38
|
* v5.0.0 — 2026-03-20 — Remove agent-related functions (replaced by OpenRouter autopilot)
|
|
39
39
|
* v5.1.0 — 2026-03-21 — Add saveProjectSettings/getProjectSettings for settings collection step
|
|
40
|
+
* v5.1.1 — 2026-06-19 — lint fixes (misleading-char-class/unused-expression/empty-block)
|
|
40
41
|
*/
|
|
41
42
|
import { apiGet, apiPost, apiPut, apiDelete } from '/js/api.js';
|
|
42
43
|
import { parse as parseYaml, stringify as stringifyYaml } from '/lib/yaml.mjs';
|
|
@@ -487,7 +488,7 @@ function cleanYaml(text) {
|
|
|
487
488
|
s = s.replace(/\\_/g, '_');
|
|
488
489
|
s = s.replace(/\\\[/g, '[').replace(/\\\]/g, ']');
|
|
489
490
|
s = s.replace(/\\\{/g, '{').replace(/\\\}/g, '}');
|
|
490
|
-
s = s.replace(
|
|
491
|
+
s = s.replace(/\u200B|\u200C|\u200D|\uFEFF/g, '');
|
|
491
492
|
try {
|
|
492
493
|
const parsed = parseYaml(s);
|
|
493
494
|
return stringifyYaml(parsed, { lineWidth: 0 });
|