privateboard 0.1.37 → 0.1.40
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/boot.js +1415 -91
- package/dist/boot.js.map +1 -1
- package/dist/cli.js +1415 -91
- package/dist/cli.js.map +1 -1
- package/dist/server.js +1271 -81
- package/dist/server.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/public/__avatar3d_test.html +156 -0
- package/public/adjourn-overlay.css +2 -2
- package/public/agent-overlay.css +27 -15
- package/public/agent-overlay.js +3 -1
- package/public/agent-profile.css +331 -41
- package/public/agent-profile.js +499 -75
- package/public/app-updater.css +1 -1
- package/public/app.js +2090 -547
- package/public/avatar-3d-snap.js +205 -0
- package/public/avatar-3d.js +792 -0
- package/public/avatar-customizer.html +274 -0
- package/public/avatar3d-editor.css +240 -0
- package/public/avatar3d-editor.js +481 -0
- package/public/avatars/3d/chair.png +0 -0
- package/public/avatars/3d/first-principles.png +0 -0
- package/public/avatars/3d/historian.png +0 -0
- package/public/avatars/3d/long-horizon.png +0 -0
- package/public/avatars/3d/phenomenologist.png +0 -0
- package/public/avatars/3d/socrates.png +0 -0
- package/public/avatars/3d/user-empathy.png +0 -0
- package/public/avatars/3d/value-investor.png +0 -0
- package/public/core-avatars.js +86 -0
- package/public/home-3d-loader.js +15 -4
- package/public/home-3d-mock.js +18 -7
- package/public/home.html +80 -18
- package/public/i18n.js +279 -4
- package/public/icons/avatar_1779855104027.glb +0 -0
- package/public/icons/logo.png +0 -0
- package/public/icons/new-style.glb +0 -0
- package/public/icons/new-style2.glb +0 -0
- package/public/icons/new-style3.glb +0 -0
- package/public/icons/new-style4.glb +0 -0
- package/public/icons/new-style5.glb +0 -0
- package/public/icons/office.glb +0 -0
- package/public/icons/stuff.glb +0 -0
- package/public/index.html +203 -182
- package/public/mention-picker.js +1 -1
- package/public/new-agent.css +7 -7
- package/public/new-agent.js +46 -20
- package/public/office-viewer.html +340 -0
- package/public/onboarding.css +5 -5
- package/public/quote-cta.css +5 -4
- package/public/quote-cta.js +50 -5
- package/public/room-settings.css +24 -9
- package/public/stuff-viewer.html +330 -0
- package/public/thread.css +1211 -0
- package/public/user-settings.css +16 -19
- package/public/user-settings.js +86 -78
- package/public/vendor/BufferGeometryUtils.js +1434 -0
- package/public/vendor/DRACOLoader.js +739 -0
- package/public/vendor/GLTFLoader.js +4860 -0
- package/public/vendor/RoomEnvironment.js +185 -0
- package/public/vendor/SkeletonUtils.js +496 -0
- package/public/vendor/draco/draco_decoder.js +34 -0
- package/public/vendor/draco/draco_decoder.wasm +0 -0
- package/public/vendor/draco/draco_encoder.js +33 -0
- package/public/vendor/draco/draco_wasm_wrapper.js +117 -0
- package/public/vendor/meshopt_decoder.module.js +196 -0
- package/public/voice-3d-banner.js +12 -0
- package/public/voice-3d.js +1407 -432
- package/public/voice-clone.css +875 -0
- package/public/voice-clone.js +1351 -0
- package/public/voice-replay.css +3 -3
- package/public/voice-replay.js +21 -0
- package/public/avatar-skill.js +0 -629
- package/public/icons/folded-sidebar.png +0 -0
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["/**\n * Single source of truth for the app version.\n *\n * Imported by `cli.ts` (CLI banner / `--version`), `server.ts` (the\n * `/health` payload + the `/api/version` endpoint), and bundled into\n * the frontend via the version endpoint. Bump alongside `package.json`\n * on every release — the existing `npm version <patch|minor|major>`\n * + commit pattern updates package.json automatically; this file\n * needs the matching manual bump.\n *\n * If two strings drift (bumped one but not the other), the wrong\n * number ends up surfaced in the user-facing footer or banner. Keep\n * this file as the canonical source — every callsite reads from here.\n */\nexport const VERSION = \"0.1.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["/**\n * Single source of truth for the app version.\n *\n * Imported by `cli.ts` (CLI banner / `--version`), `server.ts` (the\n * `/health` payload + the `/api/version` endpoint), and bundled into\n * the frontend via the version endpoint. Bump alongside `package.json`\n * on every release — the existing `npm version <patch|minor|major>`\n * + commit pattern updates package.json automatically; this file\n * needs the matching manual bump.\n *\n * If two strings drift (bumped one but not the other), the wrong\n * number ends up surfaced in the user-facing footer or banner. Keep\n * this file as the canonical source — every callsite reads from here.\n */\nexport const VERSION = \"0.1.40\";\n"],"mappings":";;;AAcO,IAAM,UAAU;","names":[]}
|
package/package.json
CHANGED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html><head><meta charset="utf-8"><title>avatar3d test</title>
|
|
3
|
+
<style>
|
|
4
|
+
html,body{margin:0;height:100%;background:#1a1a1a;overflow:hidden}
|
|
5
|
+
#status{position:fixed;top:8px;left:10px;color:#9fe;font:12px/1.5 monospace;z-index:9;white-space:pre-wrap;max-width:92vw}
|
|
6
|
+
#panel{position:fixed;top:8px;right:10px;z-index:9;background:rgba(0,0,0,.55);border:1px solid #444;border-radius:8px;padding:10px 12px;color:#cde;font:11px/1.6 monospace;width:230px}
|
|
7
|
+
#panel label{display:block;margin:6px 0 2px}
|
|
8
|
+
#panel input[type=range]{width:100%}
|
|
9
|
+
#panel b{color:#9fe}
|
|
10
|
+
#copy{margin-top:8px;width:100%;padding:5px;background:#2a3340;color:#cde;border:1px solid #556;border-radius:5px;cursor:pointer;font:11px monospace}
|
|
11
|
+
</style>
|
|
12
|
+
</head><body>
|
|
13
|
+
<div id="status">booting…</div>
|
|
14
|
+
<!-- Live brightness controls · drag to taste, then read the values off
|
|
15
|
+
the readout (or click "复制参数") and tell me — I'll bake them into
|
|
16
|
+
the room. -->
|
|
17
|
+
<div id="panel">
|
|
18
|
+
<label>曝光 exposure · <b id="vExp">0.70</b></label>
|
|
19
|
+
<input type="range" id="exp" min="0.2" max="1.4" step="0.01" value="0.70">
|
|
20
|
+
<label>环境强度 envIntensity · <b id="vEnv">0.35</b></label>
|
|
21
|
+
<input type="range" id="env" min="0" max="1.5" step="0.01" value="0.35">
|
|
22
|
+
<label>主光 key · <b id="vKey">0.70</b></label>
|
|
23
|
+
<input type="range" id="key" min="0" max="3" step="0.01" value="0.70">
|
|
24
|
+
<button id="copy">复制参数</button>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<!-- Classic script FIRST · catches module/import/protocol failures that a
|
|
28
|
+
top-level `import` would otherwise swallow into the console only. -->
|
|
29
|
+
<script>
|
|
30
|
+
window.__setStatus = function (msg, isErr) {
|
|
31
|
+
var el = document.getElementById("status");
|
|
32
|
+
if (!el) return;
|
|
33
|
+
el.textContent = msg;
|
|
34
|
+
el.style.color = isErr ? "#f88" : "#9fe";
|
|
35
|
+
};
|
|
36
|
+
if (location.protocol === "file:") {
|
|
37
|
+
window.__setStatus("⚠ 你是用 file:// 打开的 — 模块和 GLB 都加载不了。\n请在【运行中的 app】里访问 http://localhost:<端口>/__avatar3d_test.html", true);
|
|
38
|
+
}
|
|
39
|
+
window.addEventListener("error", function (e) {
|
|
40
|
+
// Resource (script/module) load failures arrive here as ErrorEvents.
|
|
41
|
+
var what = e.message || (e.target && (e.target.src || e.target.href)) || "unknown";
|
|
42
|
+
window.__setStatus("JS/资源错误: " + what, true);
|
|
43
|
+
}, true);
|
|
44
|
+
window.addEventListener("unhandledrejection", function (e) {
|
|
45
|
+
var r = e.reason; window.__setStatus("未处理的 Promise 拒绝: " + ((r && r.message) || r), true);
|
|
46
|
+
});
|
|
47
|
+
setTimeout(function () {
|
|
48
|
+
var el = document.getElementById("status");
|
|
49
|
+
if (el && /booting|importing|loading|building/i.test(el.textContent)) {
|
|
50
|
+
window.__setStatus(el.textContent + "\n(>6s 仍未完成 — 打开 DevTools Console 看具体报错)", true);
|
|
51
|
+
}
|
|
52
|
+
}, 6000);
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<script type="module">
|
|
56
|
+
const S = window.__setStatus;
|
|
57
|
+
(async () => {
|
|
58
|
+
try {
|
|
59
|
+
// Step 0 · is the GLB even reachable on this server? (isolates
|
|
60
|
+
// "asset not served" from "module failed to load".)
|
|
61
|
+
S("检查 GLB 可达性…");
|
|
62
|
+
const GLB = "/icons/avatar_1779855104027.glb";
|
|
63
|
+
const head = await fetch(GLB, { method: "GET", headers: { Range: "bytes=0-0" } }).catch((e) => ({ ok: false, status: "fetch失败 " + e.message }));
|
|
64
|
+
if (!head.ok && head.status !== 206 && head.status !== 200) {
|
|
65
|
+
S("GLB 拿不到: " + GLB + " → " + head.status + "(文件没被服务?)", true);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
S("加载 three…");
|
|
70
|
+
const THREE = await import("/vendor/three.module.min.js");
|
|
71
|
+
S("加载 OrbitControls…");
|
|
72
|
+
const { OrbitControls } = await import("/vendor/OrbitControls.js");
|
|
73
|
+
const { RoomEnvironment } = await import("/vendor/RoomEnvironment.js");
|
|
74
|
+
S("加载 avatar-3d skill…");
|
|
75
|
+
const av = await import("/avatar-3d.js");
|
|
76
|
+
|
|
77
|
+
const renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
|
|
78
|
+
renderer.setSize(innerWidth, innerHeight);
|
|
79
|
+
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
|
|
80
|
+
renderer.shadowMap.enabled = true;
|
|
81
|
+
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
82
|
+
// ACES tone mapping + sRGB output · the standard "make PBR look
|
|
83
|
+
// good" pair. Without tone mapping the env reflections clip / look
|
|
84
|
+
// flat; with it skin + hair get that soft filmic sheen.
|
|
85
|
+
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
86
|
+
renderer.toneMappingExposure = 0.7;
|
|
87
|
+
document.body.appendChild(renderer.domElement);
|
|
88
|
+
|
|
89
|
+
const scene = new THREE.Scene();
|
|
90
|
+
scene.background = new THREE.Color(0x222428);
|
|
91
|
+
const camera = new THREE.PerspectiveCamera(35, innerWidth / innerHeight, 0.1, 100);
|
|
92
|
+
camera.position.set(1.6, 1.7, 3.0);
|
|
93
|
+
const controls = new OrbitControls(camera, renderer.domElement);
|
|
94
|
+
controls.target.set(0, 0.9, 0);
|
|
95
|
+
controls.update();
|
|
96
|
+
|
|
97
|
+
// Image-based lighting · a PMREM-filtered procedural RoomEnvironment
|
|
98
|
+
// is what gives the materials real reflections / gloss (no HDRI
|
|
99
|
+
// file needed). This is the single biggest lever for "光泽 / 质感".
|
|
100
|
+
const pmrem = new THREE.PMREMGenerator(renderer);
|
|
101
|
+
scene.environment = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;
|
|
102
|
+
// RoomEnvironment is studio-bright · dim its contribution so it
|
|
103
|
+
// lights + reflects without washing the skin out. Keeps the gloss
|
|
104
|
+
// shape (reflections) while pulling overall exposure down.
|
|
105
|
+
scene.environmentIntensity = 0.35;
|
|
106
|
+
|
|
107
|
+
// The env map already provides ambient fill, so direct lights stay
|
|
108
|
+
// modest · a strong key + rim on top of IBL blew the faces out to
|
|
109
|
+
// pure white. One soft key for shape + a faint rim for separation.
|
|
110
|
+
scene.add(new THREE.HemisphereLight(0xffffff, 0x33384a, 0.18));
|
|
111
|
+
const dir = new THREE.DirectionalLight(0xffffff, 0.7);
|
|
112
|
+
dir.position.set(3, 6, 4); dir.castShadow = true; scene.add(dir);
|
|
113
|
+
const rim = new THREE.DirectionalLight(0xbfd4ff, 0.3);
|
|
114
|
+
rim.position.set(-4, 3, -3); scene.add(rim);
|
|
115
|
+
const ground = new THREE.Mesh(
|
|
116
|
+
new THREE.CircleGeometry(2.4, 48),
|
|
117
|
+
new THREE.MeshStandardMaterial({ color: 0x33363c, roughness: 1 }),
|
|
118
|
+
);
|
|
119
|
+
ground.rotation.x = -Math.PI / 2; ground.receiveShadow = true; scene.add(ground);
|
|
120
|
+
|
|
121
|
+
renderer.setAnimationLoop(() => { controls.update(); renderer.render(scene, camera); });
|
|
122
|
+
|
|
123
|
+
// Live brightness sliders → renderer / scene / key-light.
|
|
124
|
+
const $ = (id) => document.getElementById(id);
|
|
125
|
+
const wire = (id, vid, fn, fmt) => {
|
|
126
|
+
const el = $(id); const lab = $(vid);
|
|
127
|
+
const upd = () => { const v = parseFloat(el.value); fn(v); lab.textContent = fmt(v); };
|
|
128
|
+
el.addEventListener("input", upd); upd();
|
|
129
|
+
};
|
|
130
|
+
wire("exp", "vExp", (v) => { renderer.toneMappingExposure = v; }, (v) => v.toFixed(2));
|
|
131
|
+
wire("env", "vEnv", (v) => { scene.environmentIntensity = v; }, (v) => v.toFixed(2));
|
|
132
|
+
wire("key", "vKey", (v) => { dir.intensity = v; }, (v) => v.toFixed(2));
|
|
133
|
+
$("copy").addEventListener("click", () => {
|
|
134
|
+
const t = `exposure=${$("exp").value} envIntensity=${$("env").value} key=${$("key").value}`;
|
|
135
|
+
navigator.clipboard && navigator.clipboard.writeText(t);
|
|
136
|
+
$("copy").textContent = "已复制: " + t;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
S("下载 + 解析 GLB…");
|
|
140
|
+
await av.loadAvatar3D(GLB);
|
|
141
|
+
|
|
142
|
+
S("生成 avatar 实例…");
|
|
143
|
+
const seeds = ["yang-tianzhen", "socrates", "first-principles"];
|
|
144
|
+
seeds.forEach((seed, i) => {
|
|
145
|
+
const a = av.buildAvatar3D(seed, { height: 1.7 });
|
|
146
|
+
a.position.x = (i - 1) * 1.1;
|
|
147
|
+
a.rotation.y = 0;
|
|
148
|
+
scene.add(a);
|
|
149
|
+
});
|
|
150
|
+
S("✓ 加载完成 · " + seeds.length + " 个 avatar(拖动可旋转)");
|
|
151
|
+
} catch (e) {
|
|
152
|
+
S("ERROR: " + (e && e.stack ? e.stack : (e && e.message) || e), true);
|
|
153
|
+
}
|
|
154
|
+
})();
|
|
155
|
+
</script>
|
|
156
|
+
</body></html>
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
}
|
|
167
167
|
.adjourn-summary-val {
|
|
168
168
|
font-family: var(--font-human);
|
|
169
|
-
font-size:
|
|
169
|
+
font-size: 14px;
|
|
170
170
|
color: var(--text);
|
|
171
171
|
line-height: 1.4;
|
|
172
172
|
word-break: break-word;
|
|
@@ -356,7 +356,7 @@
|
|
|
356
356
|
}
|
|
357
357
|
.adjourn-mode-title {
|
|
358
358
|
font-family: var(--font-human);
|
|
359
|
-
font-size:
|
|
359
|
+
font-size: 14px;
|
|
360
360
|
font-weight: 600;
|
|
361
361
|
color: var(--text);
|
|
362
362
|
letter-spacing: -0.005em;
|
package/public/agent-overlay.css
CHANGED
|
@@ -36,33 +36,45 @@ img[data-agent]:hover { filter: brightness(1.15); }
|
|
|
36
36
|
width: 100%;
|
|
37
37
|
max-width: 560px;
|
|
38
38
|
max-height: calc(100vh - 60px);
|
|
39
|
-
overflow-y: auto;
|
|
40
39
|
background: var(--panel);
|
|
41
40
|
border: 0.5px solid var(--line-strong);
|
|
42
41
|
color: var(--text);
|
|
43
42
|
animation: agent-rise 0.18s ease-out;
|
|
44
|
-
/*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
/* Frame only · the scroll lives in the inner `.agent-card-scroll`
|
|
44
|
+
below. Keeping `.agent-card` a non-scrolling frame means the
|
|
45
|
+
decorative corner brackets (::before / ::after) stay pinned to the
|
|
46
|
+
card's corners instead of anchoring to the scrolled content and
|
|
47
|
+
drifting away. Flex column lets the inner scroller fill the frame
|
|
48
|
+
up to max-height. */
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
}
|
|
52
|
+
/* Inner scroll region · owns the overflow + the auto-hide scrollbar
|
|
53
|
+
that used to live on `.agent-card`. Thumb stays transparent until the
|
|
54
|
+
pointer is over the region OR it's actively being scrolled (the
|
|
55
|
+
`.is-scrolling` class is toggled by agent-overlay.js with a short
|
|
56
|
+
trailing timeout). Reserved gutter avoids layout shift on fade-in. */
|
|
57
|
+
.agent-card-scroll {
|
|
58
|
+
flex: 1;
|
|
59
|
+
min-height: 0;
|
|
60
|
+
overflow-y: auto;
|
|
49
61
|
scrollbar-width: thin;
|
|
50
62
|
scrollbar-color: transparent transparent;
|
|
51
63
|
scrollbar-gutter: stable;
|
|
52
64
|
transition: scrollbar-color 0.18s;
|
|
53
65
|
}
|
|
54
|
-
.agent-card:hover,
|
|
55
|
-
.agent-card.is-scrolling { scrollbar-color: var(--text-faint) transparent; }
|
|
56
|
-
.agent-card::-webkit-scrollbar { width: 8px; }
|
|
57
|
-
.agent-card::-webkit-scrollbar-track { background: transparent; }
|
|
58
|
-
.agent-card::-webkit-scrollbar-thumb {
|
|
66
|
+
.agent-card-scroll:hover,
|
|
67
|
+
.agent-card-scroll.is-scrolling { scrollbar-color: var(--text-faint) transparent; }
|
|
68
|
+
.agent-card-scroll::-webkit-scrollbar { width: 8px; }
|
|
69
|
+
.agent-card-scroll::-webkit-scrollbar-track { background: transparent; }
|
|
70
|
+
.agent-card-scroll::-webkit-scrollbar-thumb {
|
|
59
71
|
background: transparent;
|
|
60
72
|
border-radius: 4px;
|
|
61
73
|
transition: background 0.18s;
|
|
62
74
|
}
|
|
63
|
-
.agent-card:hover::-webkit-scrollbar-thumb,
|
|
64
|
-
.agent-card.is-scrolling::-webkit-scrollbar-thumb { background: var(--text-faint); }
|
|
65
|
-
.agent-card::-webkit-scrollbar-thumb:hover { background: var(--text-soft); }
|
|
75
|
+
.agent-card-scroll:hover::-webkit-scrollbar-thumb,
|
|
76
|
+
.agent-card-scroll.is-scrolling::-webkit-scrollbar-thumb { background: var(--text-faint); }
|
|
77
|
+
.agent-card-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-soft); }
|
|
66
78
|
@keyframes agent-rise {
|
|
67
79
|
from { transform: translateY(8px); opacity: 0; }
|
|
68
80
|
to { transform: translateY(0); opacity: 1; }
|
|
@@ -180,7 +192,7 @@ img[data-agent]:hover { filter: brightness(1.15); }
|
|
|
180
192
|
|
|
181
193
|
.agent-lens {
|
|
182
194
|
font-family: var(--sans);
|
|
183
|
-
font-size:
|
|
195
|
+
font-size: 14px;
|
|
184
196
|
line-height: 1.55;
|
|
185
197
|
color: var(--text-soft);
|
|
186
198
|
letter-spacing: -0.003em;
|
package/public/agent-overlay.js
CHANGED
|
@@ -201,6 +201,7 @@
|
|
|
201
201
|
const OVERLAY_HTML = `
|
|
202
202
|
<div class="agent-overlay" id="agent-overlay" role="dialog" aria-modal="true" aria-hidden="true">
|
|
203
203
|
<div class="agent-card" role="document">
|
|
204
|
+
<div class="agent-card-scroll">
|
|
204
205
|
<div class="agent-classification">
|
|
205
206
|
<span><span class="dot">●</span> <span data-i18n="ao_personnel_kicker">agent · personnel file</span></span>
|
|
206
207
|
<span class="right" data-i18n="ao_classified_mark">// classified</span>
|
|
@@ -303,6 +304,7 @@
|
|
|
303
304
|
<div class="meta public-only"><span data-i18n="ao_first_room_meta">first room ·</span> <span class="lime" data-i18n="ao_free">free</span></div>
|
|
304
305
|
<a href="/#convene" class="agent-card-cta public-only" data-i18n="ao_signin_cta">[ → Sign in to convene ]</a>
|
|
305
306
|
</footer>
|
|
307
|
+
</div>
|
|
306
308
|
</div>
|
|
307
309
|
</div>
|
|
308
310
|
`;
|
|
@@ -366,7 +368,7 @@
|
|
|
366
368
|
timer = setTimeout(() => node.classList.remove("is-scrolling"), 700);
|
|
367
369
|
}, { passive: true });
|
|
368
370
|
}
|
|
369
|
-
bindScrollAutoHide(card);
|
|
371
|
+
bindScrollAutoHide(card.querySelector(".agent-card-scroll"));
|
|
370
372
|
bindScrollAutoHide(card.querySelector(".agent-memory-list"));
|
|
371
373
|
|
|
372
374
|
/** Build a card from a live /api/agents record (custom directors).
|