π¦ New version release#156
Open
brentrager wants to merge 1 commit into
Open
Conversation
c767fad to
7b0966f
Compare
7b0966f to
13afa67
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@smooai/smooth@0.18.0
Minor Changes
17541b6: Big Smooth's own chat loop now hosts SEP extensions (pearl th-6d8606). The daemon loads pre-trusted extensions once at startup into a shared ExtensionHost; every chat turn registers their tools alongside the pearl/teammate tools (gated by the same AutoMode permission hook and a newly-added Narc surveillance hook on the chat registry), routes their ui/* requests onto the existing UiRelay machinery in-process (task_id
big-smooth-chatβ no HTTP-to-self), and intercepts/cmd argschat messages as extension slash commands. New routes:GET /api/ext(loaded extensions + commands) andPOST /api/ext/reload;th ext reloadnow hot-reloads the running daemon's host best-effort instead of always deferring to the next session.7a21dfa:
th bookingβ CLI for the org's Google-Calendar booking page.config get/set(merge-updates availability: timezone, days, hours via HH:MM or minutes, durations, buffer, min-notice, window, calendar + conflict calendars, display name),slots(open times rendered in the config timezone),bookings(list),block add/list/rm(manual busy time),calendars list/connect/rm(Calendly-style multiple Google account connections β connect prints the Google OAuth URL to authorize a conflict calendar), andlink(public booking URL). Available as bothth booking β¦andth api booking β¦.75d97b5:
th filesβ CLI for the Smoo AI org file system (ADR-060).ls(folders + files in a folder or root),mkdir,upload(presigned PUT from a local path, MIME inferred from extension),download(presigned GET β local file),mv/mvdir(move and/or rename;rootmoves to the org root),rm/rmdir,lock/unlock(admin deletion lock on a file or folder), and shares:share(anonymous link with--permission/--password/--expires-in-hours/--max-downloads, prints thesmoo.ai/share/<token>URL),shares(list),unshare(revoke), andinvite(tracked email invite βsmoo.ai/share/recipient/<token>). Available as bothth files β¦andth api files β¦.792f479: th pearls: schedulable pearls that speak up when due (th-01aa6a)
Pearls gain an optional
scheduled_at.th pearls schedule <id> <when>sets it(relative
+2h/30m/2d/1w/tomorrow/nowor absolute2026-07-10 09:00/RFC3339,UTC); omit
<when>to clear.th pearls duelists pearls whose time has arrived, andthe session-priming hook (
th prime) now surfaces aβ° Scheduled & duesection aboveReady to workso a scheduled pearl automatically speaks up at the next session startonce it comes due.
th pearls show/ready/listrender aβ°marker forscheduled pearls. Existing Dolt stores migrate idempotently (
ADD COLUMN IF NOT EXISTS).4f51437: SEP Phase 3 (smooth) β
th ext+ the extension host substrate.th extmanages SEP extensions:install ./path [--project] [--trust]copies a local extension directory into~/.smooth/extensions(or<repo>/.smooth/extensions), prints its declared capabilities, and prompts to trust it;listshows installed extensions with their trust state;trust <name>records trust;remove <name>deletes it. Trust is content-hashed and fail-safe β an extension only loads when it's recorded trusted in~/.smooth/extensions/trust.tomland itsextension.tomlstill hashes to the value trust was granted against (editing re-locks it), and a non-interactive install never trusts silently.smooth_code::sep_hostis the frontend host substrate: aRenderBlockmodel forset_widgetpayloads (markdown/keyvalue/progress + text fallback), theUiSinktrait that decouplesui/requestfrom the ratatui event loop,TuiUiProvider(the engineHostDelegatethat routesselect/confirm/input/notify/set_status/set_widget/set_titleonto aUiSink), the trust store, andload_trusted_host(discover β trust-gate βExtensionHost::loaddeclaring the seven TUI ui capabilities).Engine pin flipped from crates.io
0.14.0to a git rev ofsmooai-smooth-operator-coremain(SEP Phases 0β3, incl. theui_capabilitieshandshake), which is not yet in a crates.io release. Flip back to a version pin once a release publishes the extension module.The live agent runs in
smooth-operative; relaying a dispatched operative'sui/requestto the TUI is SEP Phase 6 (the daemon event surface). This ships the CLI, trust model, and tested render/host substrate it builds on.0449b2c: SEP Phase 4 (smooth) β attach extensions to the operative +
th ext reload.Operative attach (pearl th-70cd08). The dispatched worker (
smooth-operative)now discovers installed SEP extensions and loads the PRE-trusted ones into a
headless
ExtensionHostattached to itsAgent, so their tools,tool_callhooks, and turn events run in real dispatched tasks and flow out on the existing
AgentEventstdout stream. Trust is fail-safe: unattended, an unknown orcontent-changed extension is silently skipped (never prompts). The delegate is
the engine's headless default (empty
ui_capabilities,-32001 NoUIfor two-wayui/requestuntil the daemon relay, Phase 6); extension tools ride the ordinaryToolRegistry, so the NarcHook surveillance already installed applies to them.Trust store extraction.
TrustStore/TrustRecord/hash_extension/trust_pathmoved fromsmooth-code::sep_hostdown intosmooth-policy(
ext_trust) β a leaf crate both the TUI and the operative can depend on β andare re-exported from
sep_hostso theth extCLI is unchanged.Engine pin. Bumped
smooth-operator-coreto the SEP Phase 4 engine rev(command dispatch, session actions, hot reload).
th ext reload <name>. Re-validate an installed extension after editing it:re-parse the manifest, re-hash it, and (when the manifest changed) re-confirm
trust so the next host start picks up the new version. In-session live reload
(the engine's
ExtensionHost::reload) lands with the daemon relay (Phase 6).83094a4: SEP Phase 5 (smooth) β packaging, skills unification, marketplace search, legacy deletion.
th ext installgains npm/git sources. Beyond a local directory, install fromnpm:@scope/pkg[@version]orgit:host/user/repo[@ref]. npm packages are vendored under~/.smooth/extensions/.npm(annpm install --prefixtree so their deps resolve), git repos under~/.smooth/extensions/.git/<host>/<path>at the pinned ref (andnpm installed when they carry apackage.json). A~/.smooth/extensions/<name>symlink to the vendored dir is what the engine discovers, so packaged and local installs load identically through the engine's existing top-level discovery. A manifest may beextension.tomlor asmoothkey inpackage.json(synthesized intoextension.tomlat install). Trust records the source spec soth ext update [<name>]re-fetches and reconciles β an unchanged manifest keeps its trust, a changed one is re-locked (fail-safe).th ext search <query>matches a curated index shipped in the binary plus live npm packages tagged with thesmooth-extensionkeyword, printing the install command for each hit.Skills unification. A trusted extension's
[resources] skillsdirectory now feeds the one canonical skill catalog (smooth-cast) viaskills::resources_discover; each SKILL becomes a/skill:<name>with sourceextension, gated on the same content-hashed trust (an untrusted extension contributes no skills β the skill body is a prompt-injection surface). The duplicate skill parser insmooth-code(extensions.rs) is deleted;/skilland the new/extTUI command both read fromsmooth-cast.SkillSourcegains anExtensionvariant and a sharedlabel()(replacing five inlinematchcopies)./extTUI command lists installed extensions with their trust state and declared capabilities. Live command/UI dispatch into a running host reaches the TUI over the daemon event surface (SEP Phase 6).Deletions (migration verdicts). The zero-consumer
smooth-plugintrait crate is removed (in-process trait plugins are exactly what SEP rejects), and the duplicatesmooth-codeskill parser is removed in favor ofsmooth-cast.479035e: SEP Phase 6 (smooth side) β relay a dispatched operative's extension
ui/*requests to smooth-web.
A dispatched operative runs headless, so its new
HttpUiProviderrelays eachui/*request to Big Smooth over the existingSMOOTH_NARC_URL+SMOOTH_HOST_TOKENcallback channel (POST /api/ui/requestβ the same channelhost_tooluses). Big Smooth broadcasts aUiRequestserver event to connectedfrontends and, for the interactive kinds (
select/confirm/input), blocks theoperative's call until a browser answers via
POST /api/ui/answer. The newsmooth-web
UiRelaycomponent rendersselect/confirm/inputas a modal,notifyas a toast, andset_status/set_widget/set_titlein the chrome;render blocks (
markdown/keyvalue/progress/table/diff/stack, each witha
textfallback) render natively.Unattended (no client connected) an interactive request resolves to
{cancelled:true}rather than hang; underSMOOTH_AUTO_MODE=bypassaconfirmis auto-answered
{confirmed:true}(audited); otherwise it waits up toSMOOTH_UI_TIMEOUT_SECS(default 120s) then cancels.Also removes the dangling
smooth-pluginworkspace dependency entry (the cratewas deleted in Phase 5).
5e6418a: SEP Phase 8 (smooth) β render-block v2 DSL parity in both frontends.
Web (
UiRelay.tsx). The daemonui/*relay'sRenderBlocknow renders thePhase 8 interactive
widgetkind (itsbodyblock plus a legend of the declaredkeybindings) and aligns the
table/diff/stackfield names to the formalizedDSL (
columns/patch/children), accepting the pre-Phase-8 aliases(
headers/diff/items) as a fallback.TUI (
smooth_code::sep_host::RenderBlock). The terminal render-blocksubstrate gains reduced-fidelity
table(aligned columns),diff,stack(recursive), and
widget(body + keybinding legend) kinds, matching the web andthe SDK DSL, so a
widget-driven extension degrades cleanly to the terminal.Deferred (out of Phase 8 scope, follow-ups filed). Live interactive
widget/keyrouting from the TUI needs the engine-pin cutover to the Phase 8smooth-operator-core(which addsdispatch_widget_key) plus a liveUiSinkwired through the daemon relay (the daemon/auto-mode epic). Discovered
[resources] themesapplication is deferred too: it needs either the compile-timetheme.rspalette refactored to a runtime state (TUI) or theme colors plumbedthrough the daemon to the web SPA β discovery without either is dead code.
5b4d7a6: SEP Phase 7 (smooth) β
th cast modelssurfaces extension-registered providers.th cast modelsnow folds in LLM providers contributed by globally installedextensions (
~/.smooth/extensions/). Any extension that registers a provider viathe SEP
registerProvidersurface is loaded headlessly and its declared modelsare listed under an
extension <ext>.<provider>section (in--json, as<provider>/<model>ids). Model ids are filtered + sorted like gateway/localmodels; a provider left with no matching models is dropped. Loading is gated to
global extensions β a plain
th cast modelsin a repo never spawns a projectextension β and any failure yields an empty list, so extension providers are
strictly additive and can't break the core listing.
Engine pin bumped to the
smooai-smooth-operator-coregit rev carrying SEPPhase 7 (registerProvider / OAuth / proxied streaming /
session/set_model),which exposes
ExtensionHost::providers().5f7dc65: th-3be564: Big Smooth chat is now multimodal β attach images to a chat message and the assistant sees them.
Web (
smooth-webchat): a paperclip button, clipboard paste, and drag-and-drop stage image/PDF attachments; the composer shows removable thumbnails and the sent user bubble renders the images inline. Attachments ride the existingPOST /api/chat/sessions/{id}/messagesas{ content, attachments: [{ name, mime, data(base64) }] }β the field is optional, so text-only sends are unchanged.Daemon (
smooth-bigsmooth): the chat routes acceptattachments, content-address the bytes under~/.smooth/attachments/, and build a multimodal turn via the engine'sMessage::user_with_images. Images and PDFs both ride the turn asdata:media parts and auto-route togemini-2.5-flash-liteβ verified live that the gateway reads a PDF sent this way natively (it answered a question about the file's contents), so "read this PDF" works with no separate ingest pipeline. Text-only turns keep the default coding-slot model; an explicit per-requestmodelstill wins. Other document types (docx/xlsx/β¦) are marker-only until a converter lands (a docling microVM is the planned upgrade). Consumes the engine's new multimodal message/wire model via a git-rev pin bump (smooth-operator-core PRs pearl th-01c714: bracketed-paste + flatten prompt so multi-line task arrives as one TUI submissionΒ #58/pearl th-2b5f63: th cast models β list live model groups on configured providerΒ #62).4160767:
th config limitsβ CLI surface for the new@smooai/configlimits kind(SMOODEV-2306), numeric segment-resolved config that never bakes and clamps
client-side.
limits evaluate <key>POSTs to/organizations/{org}/config/limits/{key}/evaluate(same segment machinery asth config feature-flag, but the resolved value is a number; prints the rawpre-clamp value,
--jsonfor the full envelope),limits list/limits getsurface the clamp metadata (
default/min/max/step) declared in the org'sschema, and
limits set <key> <value>writes a raw numeric value (thin wrapperover
th config set β¦ --tier limit, rejecting non-finite values at parsetime). Adds a
limitvalue tier (--tier limit). Aliasedth config limit.Runtime resolution depends on the config-server route being wired separately.
66b4cb0: SMOODEV-2259 β
th api agents mint/update --extensioncarries per-agent extensionConfig (SEP extension enablement), mirroring --tool-config.Patch Changes
4fad6da: Fix pearls schema migration:
scheduled_at/tool_callsnever added to pre-existing stores (th-eba7b4)pearls.scheduled_at(th-01aa6a) andsession_messages.tool_calls(th-880f2c)shipped their migration as
ALTER TABLE ... ADD COLUMN IF NOT EXISTS, which theembedded Dolt engine rejects as a syntax error β the failure was swallowed by
let _ = β¦, so the columns were silently never added to existing databases andth pearls dueerroredtable "p" does not have column "scheduled_at". Bothnow heal through the
column_exists-gatedCOLUMN_HEALSloop inmigrate_schema(the same proven pattern aspearl_comments.seq), with aregression test that drops the columns and asserts a reopen re-adds them.
8c0f599: Redact secrets from chat
tool_callsbefore they are persisted to the Dolt session store (pearl th-0bb776). Since pearl th-880f2c,session_messagesstored tool-callargumentsandoutputJSON verbatim, forever, with zero redaction β three leak classes: (1) a user pastingcurl -H "Authorization: Bearer sk-..."that the agent runs, (2)env/printenv/git config --listoutput captured as a tool result, and (3)read_filepaths like~/.aws/credentials.DoltSessionStore::save_messagenow runs Narc'sSecretDetector::scanover each tool call's arguments and output and replaces every match with a[REDACTED:<type>]marker before the INSERT. A newredaction_applied: bool(serde-defaultfalse, so pre-existing rows still deserialize) rides along onSessionToolCallso downstream consumers know a record was scrubbed, and an audit-log entry (toolcall_redaction) fires whenever redaction happens. The live in-memory conversation is untouched β only what is written to durable storage is scrubbed. Clean tool calls are left byte-identical with the flagfalse.4c063f7:
th api crm timeline(and the timeline appended underth api crm deals show) always rendered "no activity yet". The renderer read the event array from a top-level array or aneventskey, but the API returns{ dealId, items: [...] }β soitemswas never read and every timeline looked empty, including deal lifecycle events (deal_won,deal_lost,deal_stage_changed). Now readsitems(bare-array + legacyeventsfallbacks kept).994ed34:
th api copilotβ CLI bridge to the org's always-on dashboard Copilot (smooai PR #2383, pearl th-f15107).Three subcommands mirror the org-authed copilot routes on
api.smoo.ai:th api copilot chat "<message>" [--conversation <id>] [--json]β runs a turn, prints the reply plus a compactran <tool>line per tool call. Continues an existing conversation with--conversation.th api copilot confirm <conversation-id> --approve|--declineβ resolves the destructive action a turn paused on, without resending the message.th api copilot history <conversation-id>β prints the conversation's message history.Destructive tools (e.g.
email.send) never auto-run: a turn that triggers one returns apendingActionand pauses.chatresolves it with a y/N prompt on a TTY, or the up-front--confirm/--no-confirmflag for non-interactive/agent use. With no flag on a non-TTY it prints the pending action and stops rather than guessing β--no-confirmis never a silent default. Authenticates as the logged-in user (th auth login), liketh api crm, so every tool run is audit-logged against the real person.Ships an
org-copilotmarketplace skill (claude-plugins/smooth-agent) teaching Claude Code when and how to drive the copilot (including the confirm-flow safety rules), and documents the surface indocs/Engineering/Using-th-CLI.md.4360dc0: th-fed6d9: Fix the smooth-web chat view scrolling/zooming out of whack on iOS.
The app shell used
min-h-screen(100vh β ignores the iOS toolbar/keyboard and lets content grow the page), had no viewport zoom lock, and no overscroll guard, so on iOS the chat rubber-banded, pinch/double-tap-zoomed, and the input scrolled off. Now the shell is a fixedh-dvh(dynamic viewport, keyboard/toolbar-aware) withoverflow-hidden;mainis the scroll container so content pages scroll under a pinned header; the viewport meta locks zoom (maximum-scale=1, user-scalable=no, viewport-fit=cover); andoverscroll-behavior: none+ aheight:100%html/body/#root chain stop the document from bouncing. The chat's existingh-[calc(100dvh-β¦)]sizing now resolves against a real fixed-height shell.7cfc945:
th notify <message>β¦β an agentic notify-the-human primitive. An AI agent running underth(Big Smooth / claude-driver) callsth notify "blocked, need input"to send a PUSH + in-app notification to the operator's OWN phone viaapi.smoo.ai.The message is a positional joined with spaces, so
th notify done, review the PRworks unquoted (the way an agent would call it). Options:--title(default "Smoo AI"),--priority low|medium|high|critical(default medium),--url <deepLink>, and--org-id/--orgto override the active org.Authenticates as the logged-in user (
th auth login), so there's no target to address β the human behind the session is the recipient. WrapsPOST /organizations/{org_id}/notifications/self; printsβ Notified <you@email> β pushed to N device(s), with a hint to open the Smoo AI app when no devices are registered.