Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
399 commits
Select commit Hold shift + click to select a range
c4d9256
feat(sps): parallel conversation tabs (Milestone 3 #5)
saxster Jun 6, 2026
b7ee7ba
test(skills): fix parallel-load flakiness in Skills.test.tsx + add ti…
saxster Jun 6, 2026
03cdc65
Merge branch 'main' into worktree-agentic-workflow-m1
saxster Jun 6, 2026
9d7a9c1
feat(sps): add in-workspace "You" surface + structured rules layer
saxster Jun 6, 2026
f8969cd
fix(sps): make workspace controls honest — fix Assistant toggle, wire…
saxster Jun 6, 2026
83ce354
Merge branch 'main' into UI_improvements
saxster Jun 6, 2026
89cc46c
feat(sps): P3 trust chip — co-author honors "You" rules + shows what …
saxster Jun 6, 2026
73470f9
docs(sps): explain why /work has no trust chip
saxster Jun 6, 2026
3c731a7
Merge remote-tracking branch 'origin/main' into feat/trust-chip
saxster Jun 6, 2026
f2a14ad
feat(brand): swap Hermes logo for SUKHI badge throughout app
saxster Jun 7, 2026
495423a
fix(sps): make right-panel tabs reliable — stop buttons toggling the …
saxster Jun 6, 2026
66afcee
fix(sps): honest sidebar — add collapse handle, drop dead affordances
saxster Jun 6, 2026
910b8cd
feat(sps): de-seed to single-user reality — drop the fake product team
saxster Jun 6, 2026
6ae3223
feat(sps): reframe Comments as private Notes (single-user)
saxster Jun 6, 2026
c65f13e
feat(sps): the assistant now reads your pinned notes (Phase 2b)
saxster Jun 7, 2026
07a2177
feat(sps): user-saveable templates (Phase 3)
saxster Jun 7, 2026
30a3f9c
feat(sps): columns layout block for side-by-side content (Phase 4)
saxster Jun 7, 2026
1743749
feat(sps): customizable cockpit dashboard home (Phase 5)
saxster Jun 7, 2026
b9c1579
fix(sps): right panel flush-right + a real on/off toggle
saxster Jun 7, 2026
63bfe33
refactor(sps): de-duplicate panel controls + relocate settings off th…
saxster Jun 7, 2026
e9ceafc
feat(sps): cockpit widgets — recent chats, today, agent status
saxster Jun 7, 2026
3e8b9e0
feat(sps): columns hold full nested blocks, not just rich text
saxster Jun 7, 2026
2ef0f01
chore(sps): remove dead .sps-admin-gear CSS
saxster Jun 7, 2026
84ffe3e
fix(sps): topbar controls were unclickable under the macOS drag-region
saxster Jun 7, 2026
54750a5
fix(sps): right-panel tabs were unclickable under the macOS drag-region
saxster Jun 7, 2026
784f99c
feat(sps): pin Settings to the sidebar foot (always visible)
saxster Jun 7, 2026
0148f7e
fix(sps): breadcrumb collided with macOS traffic lights when sidebar …
saxster Jun 7, 2026
55a151c
fix: settings overlay no longer re-embeds the whole SPS app
saxster Jun 7, 2026
573d500
polish(sps): disambiguate admin nav + pin Appearance to the foot
saxster Jun 7, 2026
c991fea
feat(sps): dark palette variants — Black (default), Warm, Terminal
saxster Jun 7, 2026
c271eac
feat(sps): Terminal palette now matches macOS Terminal 'Homebrew' pro…
saxster Jun 7, 2026
d815522
fix(sps): Tweaks panel close (X) didn't work
saxster Jun 7, 2026
ae3a888
fix(sps): make the Tweaks close (X) easier to hit + give clear feedback
saxster Jun 7, 2026
ce4e6ec
feat(sps): agent-maintained second brain (capture → wiki → lint loop)
saxster Jun 7, 2026
383af7f
feat(sps): operator guide — surface the ops/automation/skill checklists
saxster Jun 7, 2026
8ddd587
feat(admin): capability-review screen — what the agent can do & touch
saxster Jun 7, 2026
96d318b
feat(admin): run ledger — per-session cost rollup in Agent Insights
saxster Jun 7, 2026
28036a8
feat(cron): quality controls — freshness, failure behavior, first-run…
saxster Jun 7, 2026
79fac20
feat(approvals): opt-in auto-deny timeout with live countdown
saxster Jun 7, 2026
872e8f4
feat(chat): /compact — rewrite into a handoff brief for a fresh session
saxster Jun 7, 2026
598dace
fix(cron): parse new job id from create output — robust first-run pause
saxster Jun 7, 2026
441c98b
feat(chat): /compact seeds a fresh session with the handoff brief
saxster Jun 7, 2026
ddd6b90
test(approvals): cover countdown + opt-in auto-deny end to end
saxster Jun 7, 2026
f13912f
fix(smoke): un-stale the Tweaks selector; note run-ledger scope
saxster Jun 7, 2026
a25baf1
feat: implement Zero Trust compliance security enhancements
saxster Jun 7, 2026
e038d36
feat: implement Zero Trust compliance security enhancements
saxster Jun 7, 2026
44cc48f
feat: implement TELOS.md context, Fabric slash prompts, task ISC, and…
saxster Jun 7, 2026
2bb0bc4
feat: implement Telos Auditor, Piping Console Widget, and Pulse Spoke…
saxster Jun 7, 2026
0992629
feat: integrate Python agent core bridge (TokenJuice, Autonomy Securi…
saxster Jun 7, 2026
068f8de
feat: implement affordance-driven Butler Assistant command layer
saxster Jun 7, 2026
38c9bf8
feat: implement autopoietic SQLite skills registry, generator loop, a…
saxster Jun 7, 2026
06d1982
feat: implement Cyber-BBS Corkboard hybrid interface for SpsAgent
saxster Jun 7, 2026
9410b21
docs: add pragmatic ontology specification
saxster Jun 7, 2026
2bdc89a
cleanup(format): prettier sweep + eslint autofix across src/tests/scr…
saxster Jun 7, 2026
896a59c
cleanup(weak-type): type test fixtures + renderer-local any/lint erro…
saxster Jun 7, 2026
e485571
cleanup(unused): remove dead Versions component and unused INSTALL_CM…
saxster Jun 7, 2026
9f52804
cleanup(duplication): consolidate path->id helper and markdown fence …
saxster Jun 7, 2026
3e25e2f
cleanup(shared-types): consolidate install types into shared/install.…
saxster Jun 7, 2026
fc2bd48
cleanup(shared-types): consolidate Kanban types into shared/kanban.ts…
saxster Jun 7, 2026
a822eee
cleanup(shared-types): consolidate config-health types into shared [b…
saxster Jun 7, 2026
6cdb7a0
cleanup(shared-types): consolidate equity basket/alert types into sha…
saxster Jun 7, 2026
1298022
cleanup(shared-types): consolidate connection + chat-readiness types …
saxster Jun 7, 2026
b0c79d4
cleanup(shared-types): consolidate SkillEntry + fix skill-registry an…
saxster Jun 7, 2026
97e431a
chore(lint): honor the _-prefix convention for unused args/vars/catch…
saxster Jun 7, 2026
a3089f8
cleanup(weak-type): generic runPythonBridge, typed bridge metadata, d…
saxster Jun 7, 2026
d1ed243
fix(types): correct readMemory IPC contract; remove unsafe casts
saxster Jun 7, 2026
a51fa0a
cleanup(shared-types): consolidate profile/cronjob/claw3d/session IPC…
saxster Jun 7, 2026
5c90a06
cleanup(duplication): consolidate renderer SessionRow into SpsAgent/t…
saxster Jun 7, 2026
66e7e6a
cleanup(unused): remove dead exported helpers and closed-bug repro sc…
saxster Jun 7, 2026
2e99e07
chore: gitignore scratch/ local-experiment dir
saxster Jun 7, 2026
9af1b47
feat: add automated tests for newsroom curator and vault semantic search
saxster Jun 8, 2026
9b9db39
feat: add news curation settings, topic preferences, and styling alig…
saxster Jun 8, 2026
e39bb03
refactor: modularize main process IPC handlers and optimize SQLite re…
saxster Jun 8, 2026
1f7765f
Refactor main process: Consolidate permission request handlers, SSRF …
saxster Jun 8, 2026
f3c5b5a
refactor: decompose monolithic hermes.ts and installer.ts modules
saxster Jun 8, 2026
ef9a056
refactor(ui): UI/UX deep dive refactoring, styling cleanup and retro …
saxster Jun 8, 2026
8f0ca95
Upgrade knowledge graph to interactive force layout, add Obsidian not…
saxster Jun 8, 2026
0a4de13
feat(ui): unify border styling, implement window state caching and ex…
saxster Jun 8, 2026
52d331e
feat: implement macOS Accessibility JXA Skill, launchd cron autonomy,…
saxster Jun 8, 2026
bab6318
fix(smoke): stabilize playwright smoke tests for settings navigation,…
saxster Jun 8, 2026
c209827
feat: Redesign SPS BBS terminal to implement modern, active workspace…
saxster Jun 8, 2026
44ac912
feat: Redesign SPS BBS as a full-screen retro terminal dashboard
saxster Jun 8, 2026
9f32d91
feat(bbs): polish SPS BBS cockpit typography, scale calendar, restruc…
saxster Jun 8, 2026
d50e2f9
feat(bbs): remove BBS page and terminal component completely
saxster Jun 8, 2026
ddb67b1
feat(bbs): remove residual BBS/corkboard variables, types, skin token…
saxster Jun 8, 2026
858f848
feat(bbs): remove board from Surface type in storeTypes.ts
saxster Jun 8, 2026
a589c4b
feat: restructure sidebar, migrate vault health to settings, fix rese…
saxster Jun 8, 2026
ca52f59
feat: implement typed wikilinks, GraphView styling, Dream Cycle backg…
saxster Jun 8, 2026
a090cfb
refactor: remove dead yaml-path.ts parser
saxster Jun 9, 2026
7e29698
chore: retire sps-agent-prototype/ legacy design prototype
saxster Jun 9, 2026
26b5b74
refactor: extract appendAuditLog into audit-log.ts to break import cycle
saxster Jun 9, 2026
519457a
refactor: single source for CredentialPoolEntry (#367)
saxster Jun 9, 2026
37bbd13
refactor: hoist requireLocalWorkspace into one shared guard
saxster Jun 9, 2026
88cc0a1
refactor: decompose config.ts into focused config/ modules
saxster Jun 9, 2026
7ce2880
refactor: split ipc/workspace.ts junk-drawer into per-domain modules
saxster Jun 9, 2026
b58f978
feat: connection-capability matrix + fix registerDualHandler remote f…
saxster Jun 9, 2026
c6452d3
refactor: split preload hermesAPI into per-domain bridge modules
saxster Jun 9, 2026
e45536d
refactor: extract ChatOrchestrator from the send-message god-handler
saxster Jun 9, 2026
493f4c4
feat: deep-linkable admin overlay + fix dead menu shortcuts
saxster Jun 9, 2026
1ce9069
feat: status chip, single-profile cleanup, themed dialogs (Tranche A)
saxster Jun 9, 2026
6524cb6
feat: group admin nav, add Memory tab, rename overlay (Tranche B1/B2/B4)
saxster Jun 9, 2026
3d23ed1
feat: split Settings into tabbed sub-navigation (Tranche B3)
saxster Jun 9, 2026
bff2ad8
refactor: move Skills Curator out of Schedules into Skills (Tranche B5)
saxster Jun 9, 2026
fd2a48b
feat: a11y + recovery polish — aria-labels, focus trap, loading, Remo…
saxster Jun 9, 2026
1b6723b
feat: convert SidebarAgents nav-item to button for accessibility
saxster Jun 9, 2026
80f6b50
feat: convert main Sidebar nav items to buttons for accessibility
saxster Jun 9, 2026
aaf4948
feat: convert Workspace Tools Sidebar items to buttons for accessibility
saxster Jun 9, 2026
b1334f9
feat: finish sidebar button conversion — nested-click rows + section …
saxster Jun 9, 2026
981f9de
fix: reconcile the two theme controls so they can't desync (C6)
saxster Jun 9, 2026
4d7376d
feat: chat IA Stage 1 — rename/re-tier the AI surfaces (D8 Stage 1)
saxster Jun 9, 2026
96ea7af
feat: first-run checklist + open Providers post-setup (D7, checklist …
saxster Jun 9, 2026
0e0ac52
refactor: merge the two chat surfaces into one (chat-merge Step 1)
saxster Jun 9, 2026
634db48
feat: Developer mode gates worktree + checkpoints in chat (chat-merge…
saxster Jun 9, 2026
1c093b0
feat: three-tier ChatHeader with "⋯" overflow menu (chat-merge Step 4)
saxster Jun 9, 2026
150596d
fix: scope first-run checklist to the doc surface (no chat-input over…
saxster Jun 9, 2026
54a47a2
refactor: remove the OpenClaw migration feature
saxster Jun 9, 2026
945d2e3
refactor: remove the Claw3D integration entirely
saxster Jun 9, 2026
f37f021
fix: show the session's human title in the chat header
saxster Jun 9, 2026
3838e75
docs: add chat-merge dogfood report (all findings since resolved)
saxster Jun 9, 2026
b830304
fix(chat): streaming terminal-state safety (audit HIGH-1, MED-1/5/6, …
saxster Jun 9, 2026
0c60f14
fix(chat): renderer UI/a11y bugs (audit MED-4, LOW-2, LOW-5)
saxster Jun 9, 2026
b64139f
fix(sps-agent): fence untrusted vault/KB content in system prompt (au…
saxster Jun 9, 2026
8a9c64e
fix(config): allowlisted provider-key choke point for the AI config a…
saxster Jun 9, 2026
cb42378
fix(sps): remove first-run "Get started" checklist
saxster Jun 9, 2026
147843a
feat(sps): compounding Query — "Save to wiki" files grounded answers …
saxster Jun 9, 2026
de506ec
feat(sps): append-only wiki-evolution log.md (Karpathy's log.md)
saxster Jun 9, 2026
9ad92a7
feat(sps): LLM Lint — semantic health-check that proposes fixes
saxster Jun 9, 2026
de2a517
feat(sps): LLM-Wiki index.md catalog + meta-page orphan hygiene
saxster Jun 9, 2026
dd6882e
chore(sps): keep diffs minimal — drop incidental auto-format churn
saxster Jun 9, 2026
a88484a
feat(onboarding): full-screen first-run onboarding for SPS Agent
saxster Jun 9, 2026
6863828
feat(sps): research any topic on the live web → auto-file a cited pag…
saxster Jun 9, 2026
3d12b9c
fix(gateway): send local API server key from getRemoteAuthHeader (unb…
saxster Jun 9, 2026
aa24cbf
fix(sps): harden research-to-KB reliability (force web search, cap br…
saxster Jun 9, 2026
f063e3f
test(sps): add live research→KB smoke harness (real gateway)
saxster Jun 9, 2026
a31b210
docs(sps): spec for Scheduled Research (recurring research → smart-me…
saxster Jun 9, 2026
000a176
feat(sps): Scheduled Research MVP — recurring research → smart-merge …
saxster Jun 9, 2026
be4048f
feat(sps): Telegram PR1 — beginner setup wizard + Scheduled-Research …
saxster Jun 9, 2026
8780af5
feat(sps): Telegram PR2 — secure read/info-only remote control + stat…
saxster Jun 9, 2026
586fdbb
feat(chat,sps): load skills into chat via /skill-name (Claude-Code st…
saxster Jun 9, 2026
b235621
feat(external-context): shared types + index-time redaction
saxster Jun 9, 2026
a13c2d8
feat(external-context): source adapters for claude-code/codex/gemini/…
saxster Jun 9, 2026
0a236f7
feat(external-context): FTS5 index, scan orchestrator, verify script
saxster Jun 9, 2026
5b8a7e0
feat(external-context): IPC, preload bridge, source toggles
saxster Jun 9, 2026
464cf2f
feat(sps): external sessions search + read-only viewer
saxster Jun 9, 2026
7bc75c2
feat(sps): save external session to KB
saxster Jun 9, 2026
c55befd
feat(external-context): stdio MCP server + Hermes registration
saxster Jun 9, 2026
b2200aa
chore(external-context): Playwright smoke harness + title-redaction fix
saxster Jun 10, 2026
2b5b9e8
feat(external-context): date-filter knob (only index sessions newer t…
saxster Jun 10, 2026
aafcc3e
feat(external-context): time-windowed conversation query
saxster Jun 10, 2026
f0018c3
feat(sps): digest schedule kind + prompt builder
saxster Jun 10, 2026
f160600
feat(sps): weekly external-sessions digest run + scheduler dispatch
saxster Jun 10, 2026
3bb3eb5
feat(sps): digest UI — create + manage in the existing modals
saxster Jun 10, 2026
81269d4
test(sps): end-to-end dogfood of the weekly external-sessions digest
saxster Jun 10, 2026
456a40c
fix(sps): kind-aware copy in the Scheduled modal (dogfood #1+#2)
saxster Jun 10, 2026
6cfb60b
feat(sps): 'digest' WikiLog op so digest commits aren't labelled rese…
saxster Jun 10, 2026
62331cd
feat(sps): expose cadence + source scope on digest creation (dogfood #4)
saxster Jun 10, 2026
64a9254
feat(gateway): permanent supervisor with auto-recovery + health push …
saxster Jun 10, 2026
e90d3c2
feat(scheduler): self-healing routine locks + reap + skip telemetry (…
saxster Jun 10, 2026
0478307
feat(ssh): clear cached remote API key on mode change / teardown (P1.4)
saxster Jun 10, 2026
f13e841
feat(notes): emit sps-index-rebuilt so search/graph refetch (P1.7)
saxster Jun 10, 2026
624c488
feat(log): structured JSON-lines logger + rotation (P1.6)
saxster Jun 10, 2026
a3e2e27
chore(lint): resolve all 60 eslint errors → 0 (repo-wide)
saxster Jun 10, 2026
61d6dff
docs(plan): canonical "Home Base" P0-P5 transformation plan
saxster Jun 10, 2026
2c5fd7f
feat(ipc): structured error envelope via safeHandle wrapper (P1.3)
saxster Jun 10, 2026
08ec21f
feat(sps): workspace write-safety — serialized queue + generation gua…
saxster Jun 10, 2026
dcced1d
refactor(consolidation): delete admin Personalization screen — SPS Yo…
saxster Jun 10, 2026
a4b3922
refactor(consolidation): port cron oversight into SPS Scheduled, dele…
saxster Jun 10, 2026
f8edce5
docs(handoff): Home Base transformation — Phase 1 done, Phase 2 at 2/9
saxster Jun 10, 2026
fb408a8
refactor(consolidation): port session search into SPS, delete admin S…
saxster Jun 10, 2026
f3457e3
docs(handoff): refresh — Phase 2 at 3/9 (P2.3 merged), next P2.4
saxster Jun 10, 2026
9eff1ac
refactor(consolidation): remove duplicate admin Insights nav — SPS ow…
saxster Jun 10, 2026
0729286
refactor(consolidation): delete admin CapabilityReview — port summary…
saxster Jun 10, 2026
a8aa845
refactor(consolidation): delete admin Tools screen + computer-use IPC…
saxster Jun 10, 2026
b7c4d62
refactor(consolidation): delete admin Agents screen + admin Chat pane…
saxster Jun 10, 2026
1e4eb6e
refactor(consolidation): replace admin Kanban screen with read-only A…
saxster Jun 10, 2026
0f20d86
refactor(i18n): prune orphaned namespaces + dead nav keys after P2.4 …
saxster Jun 10, 2026
5f49e8e
docs(handoff): refresh — Phase 2 at 4/9 (P2.4 done), next P2.5/2.6
saxster Jun 10, 2026
5912d5b
feat(sps): evolve Tweaks into the Workspace Settings surface — active…
saxster Jun 10, 2026
84dcb38
refactor(consolidation): delete admin Skills screen — toggles now in …
saxster Jun 10, 2026
7db4639
docs(handoff): refresh — Phase 2 at 5/9 (2.6 core + Skills deletion d…
saxster Jun 10, 2026
f65244a
refactor(consolidation): port Memory + Soul into SPS You, delete both…
saxster Jun 10, 2026
b4567b6
refactor(consolidation): remove SPS sidebar stubs — Meetings / Shared…
saxster Jun 10, 2026
397e7ae
refactor(consolidation): extract one SpsModal chrome shell, convert 5…
saxster Jun 10, 2026
dfd78c2
feat(onboarding): first-run guided workspace seed + dismissible 3-ste…
saxster Jun 10, 2026
2001110
feat(discoverability): ⌘K commands + tooltips for Ask / Vault health …
saxster Jun 11, 2026
87e9e8a
docs(handoff): Phase 2 COMPLETE (9/9) — admin at 4-tab target, next i…
saxster Jun 11, 2026
b57fb0e
fix(security): remove dangerouslySetInnerHTML from MemoryProviders hi…
saxster Jun 11, 2026
3bbe0f4
feat(external-context): source-type plumbing for conversation imports…
saxster Jun 11, 2026
adb855e
feat(external-context): ChatGPT export adapter — node-graph canonical…
saxster Jun 11, 2026
80261b8
feat(external-context): Claude.ai + Grok-export import adapters (P3.3)
saxster Jun 11, 2026
1eed9db
feat(external-context): Gemini Takeout import adapter (P3.4)
saxster Jun 11, 2026
c426f3a
feat(external-context): import IPC + drop-zone UI for conversation ex…
saxster Jun 11, 2026
8073611
docs(handoff): Phase 3 COMPLETE — external conversation imports (orig…
saxster Jun 11, 2026
dd9cdfb
docs(plan): durable remaining-work plan for Home Base (P1.7 + P4 + P5)
saxster Jun 11, 2026
147bd0c
feat(sps-vault): persisted vault-mirror failure counter (P1.7)
saxster Jun 11, 2026
04d8e41
feat(note-index): project mtime into note search hits (P4 prep)
saxster Jun 11, 2026
888ebe3
feat(federated-search): fan-out aggregator + pure ranking + IPC (P4)
saxster Jun 11, 2026
39ada82
feat(ask-pane): federated results list + transcript routing (P4)
saxster Jun 11, 2026
ae597f2
feat(external-context): paste-capture for no-export tools (P5.1)
saxster Jun 11, 2026
f0645c1
feat(telegram): connection status + pairing management + allowlist in…
saxster Jun 11, 2026
ee530db
feat(ask-pane): stream the LLM "Answer" token-by-token (P5.3)
saxster Jun 11, 2026
28506c9
feat(telegram): remove the Telegram feature end-to-end (owner-declined)
saxster Jun 11, 2026
c579bf7
feat: add Learn This and clean SPS verification
saxster Jun 12, 2026
90e54ed
feat: add source study workflow
saxster Jun 12, 2026
2d80c74
Add capability risk admission checks
saxster Jun 12, 2026
ad30245
Enforce capability risk admission
saxster Jun 13, 2026
fbb7b14
feat: add support for WhatsApp Cloud platform connections
saxster Jun 13, 2026
d4cf839
feat: implement core agent resilience patterns (Context Compressor, C…
saxster Jun 13, 2026
204d4b5
feat: implement unified sub-surfaces, zero-friction context capturer,…
saxster Jun 13, 2026
d3884a0
style: resolve styling and accessibility issues in ChatInput, QuickCa…
saxster Jun 13, 2026
2bf63cc
style: fix empty rulesets, standard line-clamp properties, App inline…
saxster Jun 13, 2026
f4d52fe
style: remove inline styles in Sidebar and DocHeader
saxster Jun 13, 2026
795ca67
feat(sps): implement personal health dashboard and RSS reader; resolv…
saxster Jun 13, 2026
f3337b6
feat(skills): implement uninstallation support for local and registry…
saxster Jun 14, 2026
923b857
fix(tests): resolve signature mismatch and unused args in uninstall-s…
saxster Jun 14, 2026
f9c5e60
test(sps-smoke): fix command palette trigger in smoke test
saxster Jun 14, 2026
459f7fd
Refactor database views, sidebar navigation, and clean up inline CSS …
saxster Jun 14, 2026
c4a25a7
feat: add active work workspace surface
saxster Jun 15, 2026
02b56f2
chore: clean lint and stabilize tests
saxster Jun 15, 2026
0f61408
Add Obsidian-style SPS foundations
saxster Jun 15, 2026
c02033a
Add Research Reach integration
saxster Jun 15, 2026
3519dbf
Steer research reach toward Substack feeds
saxster Jun 15, 2026
89c33d4
feat: add Substack RSS feed flow
saxster Jun 16, 2026
d7c111f
Add agentic vault review operations
saxster Jun 15, 2026
1b8b90b
feat: expose NotebookLM MCP study sources
saxster Jun 15, 2026
5f8a036
docs: plan Substack radar browser discovery
saxster Jun 16, 2026
7112bcd
feat: add Substack radar scoring helpers
saxster Jun 16, 2026
7640d84
fix: parse grouped Substack radar counts
saxster Jun 16, 2026
6c6a5cf
feat: extract visible Substack discovery cards
saxster Jun 16, 2026
f71ce02
fix: harden Substack radar browser extraction
saxster Jun 16, 2026
239052c
fix: wait for settled Substack radar cards
saxster Jun 16, 2026
8080320
fix: sandbox Substack radar browser requests
saxster Jun 16, 2026
090ce0e
feat: add Substack radar IPC store
saxster Jun 16, 2026
2161f4b
fix: validate Substack radar status writes
saxster Jun 16, 2026
fb36452
feat: expose Substack radar preload APIs
saxster Jun 16, 2026
0fbab13
fix: type Substack radar preload results
saxster Jun 16, 2026
0f6788d
feat: add Substack radar review panel
saxster Jun 16, 2026
d720947
fix: harden Substack radar panel state
saxster Jun 16, 2026
fe87b2c
fix: share Substack radar DTOs
saxster Jun 16, 2026
c83d71f
fix: guard Substack radar preview results
saxster Jun 16, 2026
fa9a2ac
fix: synchronize Substack radar active run guard
saxster Jun 16, 2026
000eb13
fix: invalidate Substack radar preview on discovery
saxster Jun 16, 2026
8f767dc
feat: add approved Substack radar feeds to RSS
saxster Jun 16, 2026
e88ad16
fix: reflect added Substack radar feeds in UI
saxster Jun 16, 2026
69d4659
style: polish Substack radar panel
saxster Jun 16, 2026
df54361
docs: document Substack radar flow
saxster Jun 16, 2026
b1f4431
docs: clarify Substack radar browser session
saxster Jun 16, 2026
5fcd85d
Complete assistant recipe affordance
saxster Jun 16, 2026
66d0023
feat: unify source intake with crawl4ai
saxster Jun 16, 2026
bcd6f71
Add SPS Content Studio loop
saxster Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
312 changes: 312 additions & 0 deletions .agents/lib/agent_core_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
#!/usr/bin/env python3
import sys
import json
import argparse
from pathlib import Path

# Add current directory to path to import local modules
sys.path.insert(0, str(Path(__file__).parent.resolve()))

from token_juice import TokenJuice
from autonomy_security import AutonomySecurity, AutonomyTier, CommandClass, Decision
from memory_tree import MemoryTreeManager

def cmd_compress(args):
compressor = TokenJuice()
result = compressor.compress(args.text, args.tool)
print(json.dumps({"compressed": result}))

def cmd_classify_command(args):
security = AutonomySecurity(args.action_dir or str(Path.cwd()))
cmd_args = json.loads(args.args)
cmd_class = security.classify_command(cmd_args)
print(json.dumps({"class": cmd_class.value}))

def cmd_is_path_allowed(args):
security = AutonomySecurity(args.action_dir)
allowed = security.is_path_allowed(args.path)
print(json.dumps({"allowed": allowed}))

def cmd_evaluate_execution(args):
security = AutonomySecurity(args.action_dir)
cmd_args = json.loads(args.args)
tier = AutonomyTier(args.tier)
paths = json.loads(args.paths) if args.paths else None

decision, reason = security.evaluate_command_execution(cmd_args, tier, paths)
print(json.dumps({
"decision": decision.value,
"reason": reason
}))

def cmd_memory_save(args):
manager = MemoryTreeManager(args.vault)
meta = json.loads(args.meta)
manager.save_page(args.id, meta, args.body)
print(json.dumps({"status": "success"}))

def cmd_memory_search(args):
manager = MemoryTreeManager(args.vault)
results = manager.search(args.query)
print(json.dumps({"results": [{"id": r[0], "score": r[1]} for r in results]}))

def cmd_memory_graph(args):
manager = MemoryTreeManager(args.vault)
outgoing, backlinks = manager.build_link_graph()

# Convert sets to lists for JSON serialization
serialized_outgoing = {k: list(v) for k, v in outgoing.items()}
serialized_backlinks = {k: list(v) for k, v in backlinks.items()}

print(json.dumps({
"outgoing": serialized_outgoing,
"backlinks": serialized_backlinks
}))

def resolve_db_path():
import os
hermes_home = os.environ.get("HERMES_HOME")
if not hermes_home:
hermes_home = str(Path.home() / ".hermes")

active_profile_file = Path(hermes_home) / "active_profile"
profile_name = "default"
if active_profile_file.exists():
try:
profile_name = active_profile_file.read_text().strip() or "default"
except:
pass

if profile_name != "default":
return str(Path(hermes_home) / "profiles" / profile_name / "state.db")
else:
return str(Path(hermes_home) / "state.db")

def cmd_lookup_skill(args):
import sqlite3
db_path = resolve_db_path()
if not Path(db_path).exists():
print(json.dumps({"results": []}))
return

try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()

# Check if table exists
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='skills_registry'")
if not cursor.fetchone():
print(json.dumps({"results": []}))
conn.close()
return

query = args.query.lower()
words = [w for w in query.split() if w]

if not words:
cursor.execute("SELECT name, description, keywords, status, entrypoint, dependencies FROM skills_registry LIMIT 10")
rows = cursor.fetchall()
else:
clauses = []
params = []
for word in words:
clauses.append("(LOWER(name) LIKE ? OR LOWER(description) LIKE ? OR LOWER(keywords) LIKE ?)")
like_val = f"%{word}%"
params.extend([like_val, like_val, like_val])

sql = f"SELECT name, description, keywords, status, entrypoint, dependencies FROM skills_registry WHERE {' AND '.join(clauses)} LIMIT 5"
cursor.execute(sql, params)
rows = cursor.fetchall()

results = []
for r in rows:
results.append({
"name": r[0],
"description": r[1],
"keywords": r[2],
"status": r[3],
"entrypoint": r[4],
"dependencies": r[5]
})

print(json.dumps({"results": results}))
conn.close()
except Exception as e:
print(json.dumps({"error": str(e)}))

def cmd_scaffold_skill(args):
import sqlite3
import subprocess
import os

hermes_home = os.environ.get("HERMES_HOME")
if not hermes_home:
hermes_home = str(Path.home() / ".hermes")

active_profile_file = Path(hermes_home) / "active_profile"
profile_name = "default"
if active_profile_file.exists():
try:
profile_name = active_profile_file.read_text().strip() or "default"
except:
pass

if profile_name != "default":
p_home = str(Path(hermes_home) / "profiles" / profile_name)
else:
p_home = hermes_home

slug = args.name.lower().replace(" ", "-")
slug = "".join([c for c in slug if c.isalnum() or c == "-"])

skill_dir = Path(p_home) / "skills" / "custom" / slug
try:
skill_dir.mkdir(parents=True, exist_ok=True)

# Write SKILL.md
skill_md = (
f"---\n"
f"name: \"{args.name}\"\n"
f"description: \"{args.desc}\"\n"
f"keywords: \"custom, autopoietic, generated\"\n"
f"---\n\n"
f"# {args.name}\n\n"
f"{args.desc}\n"
)
(skill_dir / "SKILL.md").write_text(skill_md, encoding="utf-8")

# Write main.py
(skill_dir / "main.py").write_text(args.code, encoding="utf-8")

# Handle dependencies
deps_list = [d.strip() for d in args.deps.split(",") if d.strip()] if args.deps else []
if deps_list:
(skill_dir / "requirements.txt").write_text("\n".join(deps_list), encoding="utf-8")

# Attempt pip install
python_bin = os.environ.get("HERMES_PYTHON", sys.executable)
subprocess.run(
[python_bin, "-m", "pip", "install"] + deps_list,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=30
)

# Register in SQLite
db_path = resolve_db_path()
conn = sqlite3.connect(db_path)
cursor = conn.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS skills_registry (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE,
description TEXT,
keywords TEXT,
status TEXT DEFAULT 'active',
entrypoint TEXT,
dependencies TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")

cursor.execute("""
INSERT INTO skills_registry (name, description, keywords, status, entrypoint, dependencies)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(name) DO UPDATE SET
description = excluded.description,
keywords = excluded.keywords,
entrypoint = excluded.entrypoint,
dependencies = excluded.dependencies,
status = excluded.status
""", (
args.name,
args.desc,
"custom, autopoietic, generated",
"active",
str(skill_dir / "main.py"),
json.dumps(deps_list)
))

conn.commit()
conn.close()

print(json.dumps({
"status": "success",
"path": str(skill_dir),
"entrypoint": str(skill_dir / "main.py")
}))
except Exception as e:
print(json.dumps({"error": str(e)}))

def main():
parser = argparse.ArgumentParser(description="Hermes Agent Python Core Bridge CLI")
subparsers = parser.add_subparsers(dest="command", required=True)

# Compress Command
p_compress = subparsers.add_parser("compress")
p_compress.add_argument("--text", required=True, help="Text to compress")
p_compress.add_argument("--tool", help="Tool name context")
p_compress.set_defaults(func=cmd_compress)

# Classify Command
p_classify = subparsers.add_parser("classify-command")
p_classify.add_argument("--args", required=True, help="JSON array of command arguments")
p_classify.add_argument("--action-dir", help="Sandbox action directory")
p_classify.set_defaults(func=cmd_classify_command)

# Path Allowed Command
p_path = subparsers.add_parser("is-path-allowed")
p_path.add_argument("--path", required=True, help="Path to validate")
p_path.add_argument("--action-dir", required=True, help="Sandbox action directory")
p_path.set_defaults(func=cmd_is_path_allowed)

# Evaluate Command Execution
p_eval = subparsers.add_parser("evaluate-execution")
p_eval.add_argument("--args", required=True, help="JSON array of command arguments")
p_eval.add_argument("--tier", required=True, choices=["readonly", "supervised", "full"], help="Autonomy security tier")
p_eval.add_argument("--paths", help="JSON array of paths to validate")
p_eval.add_argument("--action-dir", required=True, help="Sandbox action directory")
p_eval.set_defaults(func=cmd_evaluate_execution)

# Memory Save
p_m_save = subparsers.add_parser("memory-save")
p_m_save.add_argument("--vault", required=True, help="Path to markdown vault directory")
p_m_save.add_argument("--id", required=True, help="Page ID/slug")
p_m_save.add_argument("--meta", required=True, help="JSON object representing frontmatter metadata")
p_m_save.add_argument("--body", required=True, help="Markdown body text")
p_m_save.set_defaults(func=cmd_memory_save)

# Memory Search
p_m_search = subparsers.add_parser("memory-search")
p_m_search.add_argument("--vault", required=True, help="Path to markdown vault directory")
p_m_search.add_argument("--query", required=True, help="Search query")
p_m_search.set_defaults(func=cmd_memory_search)

# Memory Graph
p_m_graph = subparsers.add_parser("memory-graph")
p_m_graph.add_argument("--vault", required=True, help="Path to markdown vault directory")
p_m_graph.set_defaults(func=cmd_memory_graph)

# Lookup Skill Command
p_l_skill = subparsers.add_parser("lookup-skill")
p_l_skill.add_argument("--query", required=True, help="Search terms for registry")
p_l_skill.set_defaults(func=cmd_lookup_skill)

# Scaffold Skill Command
p_s_skill = subparsers.add_parser("scaffold-skill")
p_s_skill.add_argument("--name", required=True, help="Name of the skill")
p_s_skill.add_argument("--desc", required=True, help="Description of the skill")
p_s_skill.add_argument("--code", required=True, help="Python code for the main.py entrypoint")
p_s_skill.add_argument("--deps", help="Comma-separated pip dependencies")
p_s_skill.set_defaults(func=cmd_scaffold_skill)

args = parser.parse_args()
try:
args.func(args)
except Exception as e:
print(json.dumps({"error": str(e)}))
sys.exit(1)

if __name__ == "__main__":
main()
Loading