@vellumai/assistant 0.3.15 → 0.3.16
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/ARCHITECTURE.md +142 -0
- package/Dockerfile +1 -1
- package/README.md +5 -5
- package/docs/architecture/http-token-refresh.md +252 -0
- package/docs/architecture/memory.md +5 -4
- package/docs/architecture/scheduling.md +4 -88
- package/docs/runbook-trusted-contacts.md +283 -0
- package/docs/trusted-contact-access.md +247 -0
- package/package.json +1 -1
- package/scripts/ipc/check-swift-decoder-drift.ts +2 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +2 -6
- package/src/__tests__/access-request-decision.test.ts +331 -0
- package/src/__tests__/asset-materialize-tool.test.ts +7 -7
- package/src/__tests__/asset-search-tool.test.ts +15 -15
- package/src/__tests__/attachments-store.test.ts +13 -13
- package/src/__tests__/call-controller.test.ts +150 -4
- package/src/__tests__/call-conversation-messages.test.ts +2 -2
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/call-start-guardian-guard.test.ts +93 -0
- package/src/__tests__/channel-approval-routes.test.ts +108 -12
- package/src/__tests__/channel-guardian.test.ts +16 -14
- package/src/__tests__/checker.test.ts +24 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +358 -0
- package/src/__tests__/conversation-pairing.test.ts +24 -24
- package/src/__tests__/conversation-store.test.ts +36 -36
- package/src/__tests__/date-context.test.ts +179 -1
- package/src/__tests__/db-migration-rollback.test.ts +4 -7
- package/src/__tests__/deterministic-verification-control-plane.test.ts +5 -5
- package/src/__tests__/emit-signal-routing-intent.test.ts +179 -0
- package/src/__tests__/gateway-only-guard.test.ts +188 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +451 -0
- package/src/__tests__/guardian-action-copy-generator.test.ts +197 -0
- package/src/__tests__/guardian-action-followup-executor.test.ts +379 -0
- package/src/__tests__/guardian-action-followup-store.test.ts +376 -0
- package/src/__tests__/guardian-action-late-reply.test.ts +294 -0
- package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +71 -0
- package/src/__tests__/guardian-action-sweep.test.ts +9 -9
- package/src/__tests__/guardian-outbound-http.test.ts +194 -2
- package/src/__tests__/guardian-verification-intent-routing.test.ts +179 -0
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +141 -0
- package/src/__tests__/handlers-telegram-config.test.ts +6 -6
- package/src/__tests__/hooks-runner.test.ts +13 -4
- package/src/__tests__/ingress-routes-http.test.ts +443 -0
- package/src/__tests__/intent-routing.test.ts +14 -0
- package/src/__tests__/ipc-snapshot.test.ts +2 -5
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
- package/src/__tests__/memory-regressions.test.ts +16 -12
- package/src/__tests__/non-member-access-request.test.ts +282 -0
- package/src/__tests__/notification-decision-strategy.test.ts +136 -0
- package/src/__tests__/notification-routing-intent.test.ts +11 -1
- package/src/__tests__/notification-thread-candidates.test.ts +166 -0
- package/src/__tests__/recording-intent.test.ts +1 -0
- package/src/__tests__/recording-state-machine.test.ts +328 -17
- package/src/__tests__/registry.test.ts +17 -8
- package/src/__tests__/relay-server.test.ts +105 -0
- package/src/__tests__/reminder.test.ts +13 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +4 -4
- package/src/__tests__/scheduler-recurrence.test.ts +50 -0
- package/src/__tests__/server-history-render.test.ts +8 -8
- package/src/__tests__/session-agent-loop.test.ts +1 -0
- package/src/__tests__/session-runtime-assembly.test.ts +49 -0
- package/src/__tests__/session-skill-tools.test.ts +1 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +11 -3
- package/src/__tests__/slack-channel-config.test.ts +230 -0
- package/src/__tests__/subagent-manager-notify.test.ts +4 -4
- package/src/__tests__/swarm-session-integration.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +43 -0
- package/src/__tests__/task-management-tools.test.ts +3 -3
- package/src/__tests__/task-tools.test.ts +3 -3
- package/src/__tests__/trust-store.test.ts +17 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +491 -0
- package/src/__tests__/trusted-contact-multichannel.test.ts +409 -0
- package/src/__tests__/trusted-contact-verification.test.ts +360 -0
- package/src/__tests__/update-bulletin-format.test.ts +119 -0
- package/src/__tests__/update-bulletin-state.test.ts +129 -0
- package/src/__tests__/update-bulletin.test.ts +260 -0
- package/src/__tests__/update-template-contract.test.ts +29 -0
- package/src/agent/loop.ts +2 -2
- package/src/amazon/client.ts +2 -3
- package/src/calls/call-controller.ts +115 -34
- package/src/calls/call-conversation-messages.ts +2 -2
- package/src/calls/call-domain.ts +10 -3
- package/src/calls/call-pointer-messages.ts +17 -5
- package/src/calls/guardian-action-sweep.ts +77 -36
- package/src/calls/relay-server.ts +51 -12
- package/src/calls/twilio-routes.ts +3 -1
- package/src/calls/types.ts +1 -1
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/core-commands.ts +3 -3
- package/src/cli/map.ts +8 -5
- package/src/config/bundled-skills/phone-calls/SKILL.md +16 -1
- package/src/config/bundled-skills/tasks/SKILL.md +1 -1
- package/src/config/bundled-skills/tasks/TOOLS.json +4 -4
- package/src/config/bundled-skills/time-based-actions/SKILL.md +11 -1
- package/src/config/computer-use-prompt.ts +1 -0
- package/src/config/core-schema.ts +16 -0
- package/src/config/env-registry.ts +1 -0
- package/src/config/env.ts +16 -1
- package/src/config/memory-schema.ts +5 -0
- package/src/config/schema.ts +4 -0
- package/src/config/system-prompt.ts +69 -2
- package/src/config/templates/BOOTSTRAP.md +1 -1
- package/src/config/templates/IDENTITY.md +8 -4
- package/src/config/templates/SOUL.md +14 -0
- package/src/config/templates/UPDATES.md +16 -0
- package/src/config/templates/USER.md +5 -1
- package/src/config/types.ts +1 -0
- package/src/config/update-bulletin-format.ts +52 -0
- package/src/config/update-bulletin-state.ts +49 -0
- package/src/config/update-bulletin.ts +82 -0
- package/src/config/vellum-skills/catalog.json +6 -0
- package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
- package/src/config/vellum-skills/guardian-verify-setup/SKILL.md +44 -10
- package/src/config/vellum-skills/telegram-setup/SKILL.md +4 -4
- package/src/config/vellum-skills/trusted-contacts/SKILL.md +147 -0
- package/src/config/vellum-skills/twilio-setup/SKILL.md +2 -2
- package/src/context/window-manager.ts +43 -3
- package/src/daemon/config-watcher.ts +1 -0
- package/src/daemon/connection-policy.ts +21 -1
- package/src/daemon/daemon-control.ts +164 -7
- package/src/daemon/date-context.ts +174 -1
- package/src/daemon/guardian-action-generators.ts +175 -0
- package/src/daemon/guardian-verification-intent.ts +120 -0
- package/src/daemon/handlers/apps.ts +1 -3
- package/src/daemon/handlers/config-channels.ts +2 -2
- package/src/daemon/handlers/config-heartbeat.ts +1 -1
- package/src/daemon/handlers/config-inbox.ts +55 -159
- package/src/daemon/handlers/config-ingress.ts +1 -1
- package/src/daemon/handlers/config-integrations.ts +1 -1
- package/src/daemon/handlers/config-platform.ts +1 -1
- package/src/daemon/handlers/config-scheduling.ts +2 -2
- package/src/daemon/handlers/config-slack-channel.ts +190 -0
- package/src/daemon/handlers/config-telegram.ts +1 -1
- package/src/daemon/handlers/config-twilio.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +100 -0
- package/src/daemon/handlers/config.ts +3 -0
- package/src/daemon/handlers/misc.ts +83 -5
- package/src/daemon/handlers/navigate-settings.ts +27 -0
- package/src/daemon/handlers/recording.ts +270 -144
- package/src/daemon/handlers/sessions.ts +100 -17
- package/src/daemon/handlers/subagents.ts +3 -3
- package/src/daemon/handlers/work-items.ts +10 -7
- package/src/daemon/ipc-contract/integrations.ts +9 -1
- package/src/daemon/ipc-contract/messages.ts +4 -0
- package/src/daemon/ipc-contract/sessions.ts +1 -1
- package/src/daemon/ipc-contract/settings.ts +26 -0
- package/src/daemon/ipc-contract/shared.ts +2 -0
- package/src/daemon/ipc-contract/work-items.ts +1 -7
- package/src/daemon/ipc-contract-inventory.json +5 -1
- package/src/daemon/ipc-contract.ts +5 -1
- package/src/daemon/lifecycle.ts +306 -266
- package/src/daemon/recording-intent.ts +0 -41
- package/src/daemon/response-tier.ts +2 -2
- package/src/daemon/server.ts +6 -6
- package/src/daemon/session-agent-loop-handlers.ts +34 -9
- package/src/daemon/session-agent-loop.ts +15 -8
- package/src/daemon/session-history.ts +3 -2
- package/src/daemon/session-media-retry.ts +3 -0
- package/src/daemon/session-messaging.ts +38 -4
- package/src/daemon/session-notifiers.ts +2 -2
- package/src/daemon/session-process.ts +256 -23
- package/src/daemon/session-queue-manager.ts +2 -0
- package/src/daemon/session-runtime-assembly.ts +39 -0
- package/src/daemon/session-skill-tools.ts +13 -4
- package/src/daemon/session-tool-setup.ts +5 -6
- package/src/daemon/session.ts +19 -8
- package/src/daemon/tls-certs.ts +55 -13
- package/src/daemon/tool-side-effects.ts +13 -5
- package/src/gallery/default-gallery.ts +32 -9
- package/src/influencer/client.ts +2 -1
- package/src/memory/channel-delivery-store.ts +37 -567
- package/src/memory/channel-guardian-store.ts +66 -1317
- package/src/memory/conflict-store.ts +4 -4
- package/src/memory/conversation-attention-store.ts +0 -3
- package/src/memory/conversation-crud.ts +668 -0
- package/src/memory/conversation-queries.ts +361 -0
- package/src/memory/conversation-store.ts +45 -983
- package/src/memory/db-connection.ts +3 -0
- package/src/memory/db-init.ts +25 -0
- package/src/memory/delivery-channels.ts +175 -0
- package/src/memory/delivery-crud.ts +211 -0
- package/src/memory/delivery-status.ts +199 -0
- package/src/memory/embedding-backend.ts +70 -4
- package/src/memory/embedding-local.ts +12 -2
- package/src/memory/entity-extractor.ts +3 -8
- package/src/memory/fts-reconciler.ts +121 -0
- package/src/memory/guardian-action-store.ts +366 -3
- package/src/memory/guardian-approvals.ts +569 -0
- package/src/memory/guardian-bindings.ts +130 -0
- package/src/memory/guardian-rate-limits.ts +196 -0
- package/src/memory/guardian-verification.ts +520 -0
- package/src/memory/job-handlers/index-maintenance.ts +2 -1
- package/src/memory/job-utils.ts +8 -5
- package/src/memory/jobs-store.ts +66 -6
- package/src/memory/jobs-worker.ts +23 -1
- package/src/memory/migrations/030-guardian-action-followup.ts +21 -0
- package/src/memory/migrations/030-guardian-verification-purpose.ts +17 -0
- package/src/memory/migrations/031-conversations-thread-type-index.ts +5 -0
- package/src/memory/migrations/100-core-tables.ts +1 -1
- package/src/memory/migrations/101-watchers-and-logs.ts +4 -0
- package/src/memory/migrations/108-tasks-and-work-items.ts +1 -1
- package/src/memory/migrations/112-assistant-inbox.ts +1 -1
- package/src/memory/migrations/113-late-migrations.ts +1 -1
- package/src/memory/migrations/116-messages-fts.ts +13 -0
- package/src/memory/migrations/119-schema-indexes-and-columns.ts +37 -0
- package/src/memory/migrations/120-fk-cascade-rebuilds.ts +161 -0
- package/src/memory/migrations/index.ts +8 -3
- package/src/memory/migrations/validate-migration-state.ts +114 -15
- package/src/memory/qdrant-circuit-breaker.ts +105 -0
- package/src/memory/retriever.ts +46 -13
- package/src/memory/schema-migration.ts +3 -0
- package/src/memory/schema.ts +25 -7
- package/src/memory/search/semantic.ts +8 -90
- package/src/notifications/README.md +1 -1
- package/src/notifications/broadcaster.ts +20 -2
- package/src/notifications/conversation-pairing.ts +3 -3
- package/src/notifications/decision-engine.ts +173 -8
- package/src/notifications/deliveries-store.ts +27 -8
- package/src/notifications/preferences-store.ts +7 -7
- package/src/notifications/thread-candidates.ts +234 -0
- package/src/notifications/types.ts +18 -0
- package/src/permissions/defaults.ts +11 -1
- package/src/permissions/prompter.ts +17 -0
- package/src/permissions/trust-store.ts +2 -0
- package/src/providers/failover.ts +19 -0
- package/src/providers/registry.ts +46 -1
- package/src/runtime/approval-message-composer.ts +1 -1
- package/src/runtime/channel-guardian-service.ts +15 -3
- package/src/runtime/channel-retry-sweep.ts +7 -2
- package/src/runtime/guardian-action-conversation-turn.ts +85 -0
- package/src/runtime/guardian-action-followup-executor.ts +301 -0
- package/src/runtime/guardian-action-message-composer.ts +245 -0
- package/src/runtime/guardian-outbound-actions.ts +26 -6
- package/src/runtime/guardian-verification-templates.ts +15 -9
- package/src/runtime/http-errors.ts +93 -0
- package/src/runtime/http-server.ts +133 -44
- package/src/runtime/http-types.ts +53 -0
- package/src/runtime/ingress-service.ts +237 -0
- package/src/runtime/middleware/error-handler.ts +4 -3
- package/src/runtime/middleware/rate-limiter.ts +160 -0
- package/src/runtime/middleware/request-logger.ts +71 -0
- package/src/runtime/middleware/twilio-validation.ts +7 -6
- package/src/runtime/pending-interactions.ts +12 -0
- package/src/runtime/routes/access-request-decision.ts +215 -0
- package/src/runtime/routes/app-routes.ts +25 -18
- package/src/runtime/routes/approval-routes.ts +18 -47
- package/src/runtime/routes/attachment-routes.ts +15 -41
- package/src/runtime/routes/call-routes.ts +20 -20
- package/src/runtime/routes/channel-delivery-routes.ts +6 -5
- package/src/runtime/routes/contact-routes.ts +4 -9
- package/src/runtime/routes/conversation-attention-routes.ts +2 -1
- package/src/runtime/routes/conversation-routes.ts +26 -57
- package/src/runtime/routes/debug-routes.ts +71 -0
- package/src/runtime/routes/events-routes.ts +3 -2
- package/src/runtime/routes/guardian-approval-interception.ts +221 -0
- package/src/runtime/routes/identity-routes.ts +14 -10
- package/src/runtime/routes/inbound-conversation.ts +3 -2
- package/src/runtime/routes/inbound-message-handler.ts +527 -62
- package/src/runtime/routes/ingress-routes.ts +174 -0
- package/src/runtime/routes/integration-routes.ts +78 -16
- package/src/runtime/routes/pairing-routes.ts +11 -10
- package/src/runtime/routes/secret-routes.ts +10 -18
- package/src/runtime/verification-rate-limiter.ts +83 -0
- package/src/schedule/schedule-store.ts +13 -1
- package/src/schedule/scheduler.ts +1 -1
- package/src/security/secret-ingress.ts +5 -2
- package/src/security/secret-scanner.ts +72 -6
- package/src/subagent/manager.ts +6 -4
- package/src/swarm/plan-validator.ts +4 -1
- package/src/tasks/task-runner.ts +3 -1
- package/src/tools/browser/api-map.ts +9 -6
- package/src/tools/calls/call-start.ts +20 -0
- package/src/tools/executor.ts +50 -568
- package/src/tools/permission-checker.ts +272 -0
- package/src/tools/registry.ts +14 -6
- package/src/tools/reminder/reminder-store.ts +7 -7
- package/src/tools/reminder/reminder.ts +6 -3
- package/src/tools/secret-detection-handler.ts +301 -0
- package/src/tools/subagent/message.ts +1 -1
- package/src/tools/system/voice-config.ts +62 -0
- package/src/tools/tasks/index.ts +3 -3
- package/src/tools/tasks/work-item-list.ts +3 -3
- package/src/tools/tasks/work-item-update.ts +4 -5
- package/src/tools/tool-approval-handler.ts +192 -0
- package/src/tools/tool-manifest.ts +2 -0
- package/src/watcher/watcher-store.ts +9 -9
- package/src/work-items/work-item-runner.ts +9 -6
- /package/src/memory/migrations/{026-embeddings-nullable-vector-json.ts → 026a-embeddings-nullable-vector-json.ts} +0 -0
- /package/src/memory/migrations/{027-guardian-bootstrap-token.ts → 027a-guardian-bootstrap-token.ts} +0 -0
package/src/daemon/tls-certs.ts
CHANGED
|
@@ -42,6 +42,8 @@ function computeFingerprint(cert: X509Certificate): string {
|
|
|
42
42
|
return cert.fingerprint256.replace(/:/g, '').toLowerCase();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
type CertStatus = 'valid' | 'approaching_expiry' | 'invalid';
|
|
46
|
+
|
|
45
47
|
/**
|
|
46
48
|
* Check whether an existing cert+key pair is valid:
|
|
47
49
|
* - All three files exist (cert, key, fingerprint)
|
|
@@ -49,8 +51,12 @@ function computeFingerprint(cert: X509Certificate): string {
|
|
|
49
51
|
* - Cert is not expired
|
|
50
52
|
* - Fingerprint file exists and matches the cert
|
|
51
53
|
* - Private key is valid and matches the certificate
|
|
54
|
+
*
|
|
55
|
+
* Returns 'valid' if the cert is good, 'approaching_expiry' if it's still usable
|
|
56
|
+
* but expires within 30 days (renewal should be attempted), or 'invalid' if the
|
|
57
|
+
* cert cannot be used at all.
|
|
52
58
|
*/
|
|
53
|
-
async function
|
|
59
|
+
async function checkCertStatus(): Promise<CertStatus> {
|
|
54
60
|
const certPath = getTlsCertPath();
|
|
55
61
|
const keyPath = getTlsKeyPath();
|
|
56
62
|
const fpPath = getTlsFingerprintPath();
|
|
@@ -63,7 +69,7 @@ async function isExistingCertValid(): Promise<boolean> {
|
|
|
63
69
|
]);
|
|
64
70
|
|
|
65
71
|
if (!certExists || !keyExists || !fpExists) {
|
|
66
|
-
return
|
|
72
|
+
return 'invalid';
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
try {
|
|
@@ -76,17 +82,18 @@ async function isExistingCertValid(): Promise<boolean> {
|
|
|
76
82
|
const x509 = new X509Certificate(certPem);
|
|
77
83
|
|
|
78
84
|
// Check expiration
|
|
85
|
+
const now = new Date();
|
|
79
86
|
const notAfter = new Date(x509.validTo);
|
|
80
|
-
if (notAfter <=
|
|
87
|
+
if (notAfter <= now) {
|
|
81
88
|
log.info('Existing TLS certificate has expired, will regenerate');
|
|
82
|
-
return
|
|
89
|
+
return 'invalid';
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
// Check fingerprint matches
|
|
86
93
|
const actualFp = computeFingerprint(x509);
|
|
87
94
|
if (actualFp !== storedFp.trim()) {
|
|
88
95
|
log.info('TLS fingerprint mismatch, will regenerate');
|
|
89
|
-
return
|
|
96
|
+
return 'invalid';
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
// Verify the private key is valid and matches the certificate's public key.
|
|
@@ -95,13 +102,20 @@ async function isExistingCertValid(): Promise<boolean> {
|
|
|
95
102
|
const privateKey = createPrivateKey(keyPem);
|
|
96
103
|
if (!x509.checkPrivateKey(privateKey)) {
|
|
97
104
|
log.info('TLS private key does not match certificate, will regenerate');
|
|
98
|
-
return
|
|
105
|
+
return 'invalid';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Cert is structurally valid — check if it's approaching expiry
|
|
109
|
+
const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000;
|
|
110
|
+
if (notAfter.getTime() - now.getTime() < thirtyDaysMs) {
|
|
111
|
+
log.info('TLS certificate approaching expiry, will attempt renewal');
|
|
112
|
+
return 'approaching_expiry';
|
|
99
113
|
}
|
|
100
114
|
|
|
101
|
-
return
|
|
115
|
+
return 'valid';
|
|
102
116
|
} catch (err) {
|
|
103
117
|
log.warn({ err }, 'Failed to validate existing TLS certificate, will regenerate');
|
|
104
|
-
return
|
|
118
|
+
return 'invalid';
|
|
105
119
|
}
|
|
106
120
|
}
|
|
107
121
|
|
|
@@ -125,8 +139,9 @@ export async function ensureTlsCert(): Promise<{ cert: string; key: string; fing
|
|
|
125
139
|
const keyPath = getTlsKeyPath();
|
|
126
140
|
const fpPath = getTlsFingerprintPath();
|
|
127
141
|
|
|
128
|
-
|
|
129
|
-
|
|
142
|
+
const status = await checkCertStatus();
|
|
143
|
+
|
|
144
|
+
if (status === 'valid') {
|
|
130
145
|
const [cert, key, fingerprint] = await Promise.all([
|
|
131
146
|
readFile(certPath, 'utf-8'),
|
|
132
147
|
readFile(keyPath, 'utf-8'),
|
|
@@ -136,7 +151,34 @@ export async function ensureTlsCert(): Promise<{ cert: string; key: string; fing
|
|
|
136
151
|
return { cert, key, fingerprint: fingerprint.trim() };
|
|
137
152
|
}
|
|
138
153
|
|
|
139
|
-
|
|
154
|
+
if (status === 'approaching_expiry') {
|
|
155
|
+
// Buffer existing cert/key/fingerprint before attempting renewal.
|
|
156
|
+
// generateNewCert() overwrites key.pem in-place, so if it fails mid-flight
|
|
157
|
+
// (e.g., key written but cert generation fails), reading from disk in the
|
|
158
|
+
// catch block would return a mismatched key/cert pair.
|
|
159
|
+
const [existingCert, existingKey, existingFp] = await Promise.all([
|
|
160
|
+
readFile(certPath, 'utf-8'),
|
|
161
|
+
readFile(keyPath, 'utf-8'),
|
|
162
|
+
readFile(fpPath, 'utf-8'),
|
|
163
|
+
]);
|
|
164
|
+
try {
|
|
165
|
+
return await generateNewCert(tlsDir, certPath, keyPath, fpPath);
|
|
166
|
+
} catch (err) {
|
|
167
|
+
log.warn({ err }, 'Proactive TLS renewal failed, continuing with existing certificate');
|
|
168
|
+
return { cert: existingCert, key: existingKey, fingerprint: existingFp.trim() };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// status === 'invalid' — must regenerate, no fallback
|
|
173
|
+
return await generateNewCert(tlsDir, certPath, keyPath, fpPath);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function generateNewCert(
|
|
177
|
+
tlsDir: string,
|
|
178
|
+
certPath: string,
|
|
179
|
+
keyPath: string,
|
|
180
|
+
fpPath: string,
|
|
181
|
+
): Promise<{ cert: string; key: string; fingerprint: string }> {
|
|
140
182
|
log.info('Generating new self-signed TLS certificate');
|
|
141
183
|
await mkdir(tlsDir, { recursive: true });
|
|
142
184
|
|
|
@@ -151,13 +193,13 @@ export async function ensureTlsCert(): Promise<{ cert: string; key: string; fing
|
|
|
151
193
|
throw new Error(`Failed to generate TLS key: ${stderr}`);
|
|
152
194
|
}
|
|
153
195
|
|
|
154
|
-
// Generate self-signed cert (
|
|
196
|
+
// Generate self-signed cert (1-year validity)
|
|
155
197
|
const certProc = Bun.spawn(
|
|
156
198
|
[
|
|
157
199
|
'openssl', 'req', '-new', '-x509',
|
|
158
200
|
'-key', keyPath,
|
|
159
201
|
'-out', certPath,
|
|
160
|
-
'-days', '
|
|
202
|
+
'-days', '365',
|
|
161
203
|
'-subj', '/CN=Vellum Daemon',
|
|
162
204
|
],
|
|
163
205
|
{ stdout: 'pipe', stderr: 'pipe' },
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* registry entry instead of another if/else branch.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { normalizeActivationKey } from './handlers/config-voice.js';
|
|
10
11
|
import { updatePublishedAppDeployment } from '../services/published-app-updater.js';
|
|
11
12
|
import { openAppViaSurface } from '../tools/apps/open-proxy.js';
|
|
12
13
|
import type { ToolExecutionResult } from '../tools/types.js';
|
|
@@ -74,11 +75,6 @@ registerHook('app_update', (_name, input, _result, { ctx, broadcastToAllClients
|
|
|
74
75
|
}
|
|
75
76
|
});
|
|
76
77
|
|
|
77
|
-
// Tell the client to open/focus the tasks window when the model lists tasks
|
|
78
|
-
registerHook('task_list_show', (_name, _input, _result, { ctx }) => {
|
|
79
|
-
ctx.sendToClient({ type: 'open_tasks_window' });
|
|
80
|
-
});
|
|
81
|
-
|
|
82
78
|
// Broadcast tasks_changed so connected clients (e.g. macOS Tasks window)
|
|
83
79
|
// auto-refresh when the LLM mutates the task queue via tools
|
|
84
80
|
registerHook(
|
|
@@ -101,6 +97,18 @@ registerHook(
|
|
|
101
97
|
},
|
|
102
98
|
);
|
|
103
99
|
|
|
100
|
+
// Broadcast activation key change to all connected clients so every
|
|
101
|
+
// macOS/iOS instance picks up the new setting immediately.
|
|
102
|
+
registerHook('voice_config_update', (_name, input, _result, { broadcastToAllClients }) => {
|
|
103
|
+
const key = input.activation_key as string | undefined;
|
|
104
|
+
if (key) {
|
|
105
|
+
const normalized = normalizeActivationKey(key);
|
|
106
|
+
if (normalized.ok) {
|
|
107
|
+
broadcastToAllClients?.({ type: 'client_settings_update', key: 'activationKey', value: normalized.value });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
104
112
|
// ── Runner ───────────────────────────────────────────────────────────
|
|
105
113
|
|
|
106
114
|
/**
|
|
@@ -107,8 +107,8 @@ const focusTimerHtml = `<!DOCTYPE html>
|
|
|
107
107
|
<div class="mode-label" id="modeLabel">Work Session</div>
|
|
108
108
|
<div class="timer-display" id="timerDisplay">25:00</div>
|
|
109
109
|
<div class="controls">
|
|
110
|
-
<button class="btn-primary" id="startBtn"
|
|
111
|
-
<button class="btn-secondary" id="resetBtn"
|
|
110
|
+
<button class="btn-primary" id="startBtn">Start</button>
|
|
111
|
+
<button class="btn-secondary" id="resetBtn">Reset</button>
|
|
112
112
|
</div>
|
|
113
113
|
<div class="stats">
|
|
114
114
|
<div class="stat-item">
|
|
@@ -184,6 +184,9 @@ const focusTimerHtml = `<!DOCTYPE html>
|
|
|
184
184
|
updateDisplay();
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
document.getElementById('startBtn').addEventListener('click', toggleTimer);
|
|
188
|
+
document.getElementById('resetBtn').addEventListener('click', resetTimer);
|
|
189
|
+
|
|
187
190
|
updateDisplay();
|
|
188
191
|
</script>
|
|
189
192
|
</body>
|
|
@@ -334,8 +337,8 @@ const habitTrackerHtml = `<!DOCTYPE html>
|
|
|
334
337
|
<h1>Habit Tracker</h1>
|
|
335
338
|
</div>
|
|
336
339
|
<div class="add-form">
|
|
337
|
-
<input type="text" id="habitInput" placeholder="Add a new habit..."
|
|
338
|
-
<button class="btn-primary"
|
|
340
|
+
<input type="text" id="habitInput" placeholder="Add a new habit...">
|
|
341
|
+
<button class="btn-primary" id="addHabitBtn">Add</button>
|
|
339
342
|
</div>
|
|
340
343
|
<div class="days-header">
|
|
341
344
|
<div></div>
|
|
@@ -387,12 +390,12 @@ const habitTrackerHtml = `<!DOCTYPE html>
|
|
|
387
390
|
html += '<div class="habit-row">';
|
|
388
391
|
html += '<div style="display:flex;align-items:center;gap:8px">';
|
|
389
392
|
html += '<span class="habit-name">' + escapeHtml(record.data.name) + '</span>';
|
|
390
|
-
html += '<button class="delete-btn"
|
|
393
|
+
html += '<button class="delete-btn" data-delete-habit="'+record.id+'">x</button>';
|
|
391
394
|
html += '</div>';
|
|
392
395
|
dates.forEach(function(date) {
|
|
393
396
|
var checked = completedDates.indexOf(date) !== -1;
|
|
394
397
|
html += '<div class="check-cell">';
|
|
395
|
-
html += '<button class="check-btn' + (checked ? ' checked' : '') + '"
|
|
398
|
+
html += '<button class="check-btn' + (checked ? ' checked' : '') + '" data-toggle-habit="'+record.id+'" data-toggle-date="'+date+'">';
|
|
396
399
|
html += checked ? '\\u2713' : '';
|
|
397
400
|
html += '</button></div>';
|
|
398
401
|
});
|
|
@@ -438,6 +441,17 @@ const habitTrackerHtml = `<!DOCTYPE html>
|
|
|
438
441
|
});
|
|
439
442
|
}
|
|
440
443
|
|
|
444
|
+
document.getElementById('habitInput').addEventListener('keydown', function(event) {
|
|
445
|
+
if (event.key === 'Enter') addHabit();
|
|
446
|
+
});
|
|
447
|
+
document.getElementById('addHabitBtn').addEventListener('click', addHabit);
|
|
448
|
+
document.getElementById('habitsList').addEventListener('click', function(event) {
|
|
449
|
+
var btn = event.target.closest('[data-delete-habit]');
|
|
450
|
+
if (btn) { deleteHabit(btn.getAttribute('data-delete-habit')); return; }
|
|
451
|
+
var toggle = event.target.closest('[data-toggle-habit]');
|
|
452
|
+
if (toggle) { toggleDate(toggle.getAttribute('data-toggle-habit'), toggle.getAttribute('data-toggle-date')); }
|
|
453
|
+
});
|
|
454
|
+
|
|
441
455
|
initDates();
|
|
442
456
|
loadHabits();
|
|
443
457
|
</script>
|
|
@@ -629,9 +643,9 @@ const expenseTrackerHtml = `<!DOCTYPE html>
|
|
|
629
643
|
<option value="entertainment">Entertainment</option>
|
|
630
644
|
<option value="other">Other</option>
|
|
631
645
|
</select>
|
|
632
|
-
<input type="text" class="input-desc" id="descInput" placeholder="Description..."
|
|
646
|
+
<input type="text" class="input-desc" id="descInput" placeholder="Description...">
|
|
633
647
|
<input type="date" class="input-date" id="dateInput">
|
|
634
|
-
<button class="btn-primary"
|
|
648
|
+
<button class="btn-primary" id="addExpenseBtn">Add</button>
|
|
635
649
|
</div>
|
|
636
650
|
<div class="section-title">By Category</div>
|
|
637
651
|
<div class="categories-grid" id="categoriesGrid"></div>
|
|
@@ -693,7 +707,7 @@ const expenseTrackerHtml = `<!DOCTYPE html>
|
|
|
693
707
|
listHtml += '<div class="expense-meta">' + escapeHtml(r.data.category || 'other') + ' \\u00B7 ' + escapeHtml(r.data.date || '') + '</div>';
|
|
694
708
|
listHtml += '</div>';
|
|
695
709
|
listHtml += '<div class="expense-amount">$' + amt.toFixed(2) + '</div>';
|
|
696
|
-
listHtml += '<button class="delete-btn"
|
|
710
|
+
listHtml += '<button class="delete-btn" data-delete-expense="'+r.id+'">x</button>';
|
|
697
711
|
listHtml += '</div>';
|
|
698
712
|
});
|
|
699
713
|
}
|
|
@@ -724,6 +738,15 @@ const expenseTrackerHtml = `<!DOCTYPE html>
|
|
|
724
738
|
});
|
|
725
739
|
}
|
|
726
740
|
|
|
741
|
+
document.getElementById('descInput').addEventListener('keydown', function(event) {
|
|
742
|
+
if (event.key === 'Enter') addExpense();
|
|
743
|
+
});
|
|
744
|
+
document.getElementById('addExpenseBtn').addEventListener('click', addExpense);
|
|
745
|
+
document.getElementById('expenseList').addEventListener('click', function(event) {
|
|
746
|
+
var btn = event.target.closest('[data-delete-expense]');
|
|
747
|
+
if (btn) { deleteExpense(btn.getAttribute('data-delete-expense')); }
|
|
748
|
+
});
|
|
749
|
+
|
|
727
750
|
loadExpenses();
|
|
728
751
|
</script>
|
|
729
752
|
</body>
|
package/src/influencer/client.ts
CHANGED
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
|
|
48
48
|
import type { ExtensionCommand, ExtensionResponse } from '../browser-extension-relay/protocol.js';
|
|
49
49
|
import { extensionRelayServer } from '../browser-extension-relay/server.js';
|
|
50
|
+
import { getGatewayInternalBaseUrl } from '../config/env.js';
|
|
50
51
|
import { readHttpToken } from '../util/platform.js';
|
|
51
52
|
|
|
52
53
|
// ---------------------------------------------------------------------------
|
|
@@ -133,7 +134,7 @@ async function sendRelayCommand(command: Record<string, unknown>): Promise<Exten
|
|
|
133
134
|
);
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
const resp = await fetch(
|
|
137
|
+
const resp = await fetch(`${getGatewayInternalBaseUrl()}/v1/browser-relay/command`, {
|
|
137
138
|
method: 'POST',
|
|
138
139
|
headers: {
|
|
139
140
|
'Content-Type': 'application/json',
|