aimeat 1.33.2 → 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/locales/en.json +437 -15
- package/dist/locales/fi.json +437 -15
- package/dist/public/cortex-bundled/aimeat-charts.js +3 -3
- package/dist/public/cortex-bundled/aimeat-charts.yaml +3 -3
- package/dist/public/cortex-bundled/aimeat-i18n.js +123 -0
- package/dist/public/cortex-bundled/aimeat-i18n.yaml +64 -0
- package/dist/public/css/views/landing.css +2 -0
- package/dist/public/css/views/secretary.css +464 -2
- package/dist/public/js/i18n.js +9 -0
- package/dist/public/js/services/apps.js +4 -2
- package/dist/public/js/services/memory.js +9 -3
- package/dist/public/js/services/offers.js +1 -1
- package/dist/public/js/services/organisms.js +49 -17
- package/dist/public/js/services/secretary-helpers.js +266 -17
- package/dist/public/js/services/secretary-policy.js +28 -2
- package/dist/public/js/services/secretary-rules.js +70 -0
- package/dist/public/js/theme.js +20 -0
- package/dist/public/lib/VENDORED-STYLING.md +31 -0
- package/dist/public/lib/aimeat-daisyui-bridge.css +48 -0
- package/dist/public/lib/chartjs@4.js +14 -0
- package/dist/public/lib/daisyui@5.css +7 -0
- package/dist/public/lib/tailwindcss@4.js +8 -0
- package/dist/public/llms-template.txt +9 -6
- package/dist/public/showroom.html +104 -0
- package/dist/public/showroom.js +247 -0
- package/dist/public/spa.html +18 -16
- package/dist/public/views/aimeat-os.js +3 -2
- package/dist/public/views/landing.js +50 -6
- package/dist/public/views/profile/agents/agent-card.js +13 -4
- package/dist/public/views/profile/agents/state-detector.js +6 -0
- package/dist/public/views/profile/agents/tab-integration.js +11 -2
- package/dist/public/views/profile/apps-tab.js +46 -0
- package/dist/public/views/profile/extensions-tab.js +4 -0
- package/dist/public/views/profile/inbox-tab.js +1 -1
- package/dist/public/views/profile/landing-page.js +8 -3
- package/dist/public/views/profile/memory-tab.js +37 -6
- package/dist/public/views/profile/organisms/home.js +32 -0
- package/dist/public/views/profile/organisms/workspace-list.js +36 -5
- package/dist/public/views/profile/organisms/workspace.js +29 -4
- package/dist/public/views/profile/organisms-tab.js +61 -8
- package/dist/public/views/secretary/calendar.js +327 -0
- package/dist/public/views/secretary/cards-reach.js +16 -17
- package/dist/public/views/secretary/cards.js +217 -79
- package/dist/public/views/secretary/dashboard.js +617 -0
- package/dist/public/views/secretary/quality.js +156 -0
- package/dist/public/views/secretary/use-autonomy.js +17 -2
- package/dist/public/views/secretary/use-freshness.js +50 -0
- package/dist/public/views/secretary/use-intake.js +23 -4
- package/dist/public/views/secretary/use-layout.js +122 -0
- package/dist/public/views/secretary/use-quick-actions.js +98 -0
- package/dist/public/views/secretary/use-specialists.js +103 -0
- package/dist/public/views/secretary/use-triggers.js +159 -0
- package/dist/public/views/secretary/use-whats-next.js +340 -0
- package/dist/public/views/secretary/workflow-design.js +112 -0
- package/dist/public/views/secretary.js +836 -44
- package/dist/scripts/check-no-max-tokens.d.ts +2 -0
- package/dist/scripts/check-no-max-tokens.d.ts.map +1 -0
- package/dist/scripts/check-no-max-tokens.js +71 -0
- package/dist/scripts/check-no-max-tokens.js.map +1 -0
- package/dist/src/cli/connect/mcp/tools/organisms.d.ts +2 -0
- package/dist/src/cli/connect/mcp/tools/organisms.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/tools/organisms.js +9 -1
- package/dist/src/cli/connect/mcp/tools/organisms.js.map +1 -1
- package/dist/src/cli/connect/onboarding-prompt.d.ts +3 -0
- package/dist/src/cli/connect/onboarding-prompt.d.ts.map +1 -1
- package/dist/src/cli/connect/onboarding-prompt.js +10 -3
- package/dist/src/cli/connect/onboarding-prompt.js.map +1 -1
- package/dist/src/data/aimeat-iam-package.d.ts +25 -0
- package/dist/src/data/aimeat-iam-package.d.ts.map +1 -0
- package/dist/src/data/aimeat-iam-package.js +312 -0
- package/dist/src/data/aimeat-iam-package.js.map +1 -0
- package/dist/src/data/aimeat-marketplace-package.d.ts +25 -0
- package/dist/src/data/aimeat-marketplace-package.d.ts.map +1 -0
- package/dist/src/data/aimeat-marketplace-package.js +231 -0
- package/dist/src/data/aimeat-marketplace-package.js.map +1 -0
- package/dist/src/data/app-templates.d.ts +48 -0
- package/dist/src/data/app-templates.d.ts.map +1 -0
- package/dist/src/data/app-templates.js +856 -0
- package/dist/src/data/app-templates.js.map +1 -0
- package/dist/src/data/example-packages.d.ts.map +1 -1
- package/dist/src/data/example-packages.js +3 -1
- package/dist/src/data/example-packages.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +689 -7
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/generated/prisma-postgres/edge.js +10 -3
- package/dist/src/generated/prisma-postgres/index-browser.js +7 -0
- package/dist/src/generated/prisma-postgres/index.d.ts +205 -2
- package/dist/src/generated/prisma-postgres/index.js +10 -3
- package/dist/src/generated/prisma-postgres/package.json +1 -1
- package/dist/src/generated/prisma-postgres/schema.prisma +23 -13
- package/dist/src/generated/prisma-postgres/wasm.js +10 -3
- package/dist/src/mcp/agent-onboarding.d.ts +4 -0
- package/dist/src/mcp/agent-onboarding.d.ts.map +1 -1
- package/dist/src/mcp/agent-onboarding.js +28 -2
- package/dist/src/mcp/agent-onboarding.js.map +1 -1
- package/dist/src/mcp/annotations.d.ts.map +1 -1
- package/dist/src/mcp/annotations.js +1 -0
- package/dist/src/mcp/annotations.js.map +1 -1
- package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
- package/dist/src/mcp/catalog/definitions.js +16 -1
- package/dist/src/mcp/catalog/definitions.js.map +1 -1
- package/dist/src/mcp/catalog/surfaces.js +3 -3
- package/dist/src/mcp/catalog/surfaces.js.map +1 -1
- package/dist/src/mcp/index.d.ts +3 -0
- package/dist/src/mcp/index.d.ts.map +1 -1
- package/dist/src/mcp/index.js +11 -0
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/mcp/organisms.d.ts.map +1 -1
- package/dist/src/mcp/organisms.js +48 -8
- package/dist/src/mcp/organisms.js.map +1 -1
- package/dist/src/mcp/workspaces.d.ts.map +1 -1
- package/dist/src/mcp/workspaces.js +6 -4
- package/dist/src/mcp/workspaces.js.map +1 -1
- package/dist/src/models/agent-onboarding-schemas.d.ts +47 -0
- package/dist/src/models/agent-onboarding-schemas.d.ts.map +1 -1
- package/dist/src/models/agent-onboarding-schemas.js +117 -0
- package/dist/src/models/agent-onboarding-schemas.js.map +1 -1
- package/dist/src/models/offer-schemas.d.ts +8 -8
- package/dist/src/routes/agent-onboarding.d.ts +5 -0
- package/dist/src/routes/agent-onboarding.d.ts.map +1 -1
- package/dist/src/routes/agent-onboarding.js +21 -2
- package/dist/src/routes/agent-onboarding.js.map +1 -1
- package/dist/src/routes/ai.d.ts +8 -4
- package/dist/src/routes/ai.d.ts.map +1 -1
- package/dist/src/routes/ai.js +38 -14
- package/dist/src/routes/ai.js.map +1 -1
- package/dist/src/routes/app-grants.d.ts +2 -0
- package/dist/src/routes/app-grants.d.ts.map +1 -1
- package/dist/src/routes/app-grants.js +7 -1
- package/dist/src/routes/app-grants.js.map +1 -1
- package/dist/src/routes/app-templates.d.ts +16 -0
- package/dist/src/routes/app-templates.d.ts.map +1 -0
- package/dist/src/routes/app-templates.js +40 -0
- package/dist/src/routes/app-templates.js.map +1 -0
- package/dist/src/routes/apps.d.ts.map +1 -1
- package/dist/src/routes/apps.js +55 -5
- package/dist/src/routes/apps.js.map +1 -1
- package/dist/src/routes/auth.d.ts +3 -0
- package/dist/src/routes/auth.d.ts.map +1 -1
- package/dist/src/routes/auth.js +9 -4
- package/dist/src/routes/auth.js.map +1 -1
- package/dist/src/routes/bootstrap.d.ts.map +1 -1
- package/dist/src/routes/bootstrap.js +1 -0
- package/dist/src/routes/bootstrap.js.map +1 -1
- package/dist/src/routes/generator.d.ts.map +1 -1
- package/dist/src/routes/generator.js +3 -2
- package/dist/src/routes/generator.js.map +1 -1
- package/dist/src/routes/lib-ai.d.ts +0 -1
- package/dist/src/routes/lib-ai.d.ts.map +1 -1
- package/dist/src/routes/lib-ai.js +13 -6
- package/dist/src/routes/lib-ai.js.map +1 -1
- package/dist/src/routes/lib-header.d.ts +2 -0
- package/dist/src/routes/lib-header.d.ts.map +1 -1
- package/dist/src/routes/lib-header.js +7 -16
- package/dist/src/routes/lib-header.js.map +1 -1
- package/dist/src/routes/lib-markdown.d.ts +18 -0
- package/dist/src/routes/lib-markdown.d.ts.map +1 -0
- package/dist/src/routes/lib-markdown.js +236 -0
- package/dist/src/routes/lib-markdown.js.map +1 -0
- package/dist/src/routes/libs.d.ts +22 -0
- package/dist/src/routes/libs.d.ts.map +1 -1
- package/dist/src/routes/libs.js +133 -10
- package/dist/src/routes/libs.js.map +1 -1
- package/dist/src/routes/memory.d.ts.map +1 -1
- package/dist/src/routes/memory.js +21 -2
- package/dist/src/routes/memory.js.map +1 -1
- package/dist/src/routes/openrouter.d.ts +4 -0
- package/dist/src/routes/openrouter.d.ts.map +1 -1
- package/dist/src/routes/openrouter.js +17 -0
- package/dist/src/routes/openrouter.js.map +1 -1
- package/dist/src/routes/organisms.d.ts.map +1 -1
- package/dist/src/routes/organisms.js +107 -7
- package/dist/src/routes/organisms.js.map +1 -1
- package/dist/src/routes/portal.d.ts +9 -0
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +1 -1
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/public-stats.d.ts +3 -0
- package/dist/src/routes/public-stats.d.ts.map +1 -1
- package/dist/src/routes/public-stats.js +9 -2
- package/dist/src/routes/public-stats.js.map +1 -1
- package/dist/src/routes/secretary.d.ts +34 -0
- package/dist/src/routes/secretary.d.ts.map +1 -0
- package/dist/src/routes/secretary.js +311 -0
- package/dist/src/routes/secretary.js.map +1 -0
- package/dist/src/routes/specialists.d.ts.map +1 -1
- package/dist/src/routes/specialists.js +21 -0
- package/dist/src/routes/specialists.js.map +1 -1
- package/dist/src/routes/subdomains.js +1 -1
- package/dist/src/routes/subdomains.js.map +1 -1
- package/dist/src/routes/workflows.d.ts +9 -3
- package/dist/src/routes/workflows.d.ts.map +1 -1
- package/dist/src/routes/workflows.js +9 -3
- package/dist/src/routes/workflows.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +4 -0
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
- package/dist/src/server-bootstrap/service-init.js +7 -0
- package/dist/src/server-bootstrap/service-init.js.map +1 -1
- package/dist/src/server-bootstrap/static-files.d.ts +4 -0
- package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
- package/dist/src/server-bootstrap/static-files.js +18 -0
- package/dist/src/server-bootstrap/static-files.js.map +1 -1
- package/dist/src/services/archive.d.ts +74 -0
- package/dist/src/services/archive.d.ts.map +1 -0
- package/dist/src/services/archive.js +132 -0
- package/dist/src/services/archive.js.map +1 -0
- package/dist/src/services/cortex-seeder.d.ts +4 -1
- package/dist/src/services/cortex-seeder.d.ts.map +1 -1
- package/dist/src/services/cortex-seeder.js +25 -6
- package/dist/src/services/cortex-seeder.js.map +1 -1
- package/dist/src/services/directory.d.ts.map +1 -1
- package/dist/src/services/directory.js +3 -2
- package/dist/src/services/directory.js.map +1 -1
- package/dist/src/services/generator-prompt-seeds.d.ts.map +1 -1
- package/dist/src/services/generator-prompt-seeds.js +5 -4
- package/dist/src/services/generator-prompt-seeds.js.map +1 -1
- package/dist/src/services/message-send.d.ts.map +1 -1
- package/dist/src/services/message-send.js +14 -0
- package/dist/src/services/message-send.js.map +1 -1
- package/dist/src/services/onboarding-guide.d.ts +53 -0
- package/dist/src/services/onboarding-guide.d.ts.map +1 -0
- package/dist/src/services/onboarding-guide.js +81 -0
- package/dist/src/services/onboarding-guide.js.map +1 -0
- package/dist/src/services/organism-search.d.ts +6 -2
- package/dist/src/services/organism-search.d.ts.map +1 -1
- package/dist/src/services/organism-search.js +2 -2
- package/dist/src/services/organism-search.js.map +1 -1
- package/dist/src/services/owner-memory.d.ts +1 -0
- package/dist/src/services/owner-memory.d.ts.map +1 -1
- package/dist/src/services/owner-memory.js.map +1 -1
- package/dist/src/services/owner-session.d.ts +1 -0
- package/dist/src/services/owner-session.d.ts.map +1 -1
- package/dist/src/services/owner-session.js +10 -2
- package/dist/src/services/owner-session.js.map +1 -1
- package/dist/src/services/package-seeder.d.ts +22 -0
- package/dist/src/services/package-seeder.d.ts.map +1 -0
- package/dist/src/services/package-seeder.js +30 -0
- package/dist/src/services/package-seeder.js.map +1 -0
- package/dist/src/services/presence.d.ts +3 -0
- package/dist/src/services/presence.d.ts.map +1 -1
- package/dist/src/services/presence.js +10 -0
- package/dist/src/services/presence.js.map +1 -1
- package/dist/src/services/prompt-defaults.d.ts.map +1 -1
- package/dist/src/services/prompt-defaults.js +8 -3
- package/dist/src/services/prompt-defaults.js.map +1 -1
- package/dist/src/services/scheduler.d.ts +50 -2
- package/dist/src/services/scheduler.d.ts.map +1 -1
- package/dist/src/services/scheduler.js +454 -26
- package/dist/src/services/scheduler.js.map +1 -1
- package/dist/src/services/secretary-authoring.d.ts +71 -0
- package/dist/src/services/secretary-authoring.d.ts.map +1 -0
- package/dist/src/services/secretary-authoring.js +336 -0
- package/dist/src/services/secretary-authoring.js.map +1 -0
- package/dist/src/services/secretary-clarify.d.ts +57 -0
- package/dist/src/services/secretary-clarify.d.ts.map +1 -0
- package/dist/src/services/secretary-clarify.js +104 -0
- package/dist/src/services/secretary-clarify.js.map +1 -0
- package/dist/src/services/secretary-feed.d.ts +11 -0
- package/dist/src/services/secretary-feed.d.ts.map +1 -0
- package/dist/src/services/secretary-feed.js +28 -0
- package/dist/src/services/secretary-feed.js.map +1 -0
- package/dist/src/services/secretary-tick.d.ts +243 -3
- package/dist/src/services/secretary-tick.d.ts.map +1 -1
- package/dist/src/services/secretary-tick.js +273 -3
- package/dist/src/services/secretary-tick.js.map +1 -1
- package/dist/src/services/secretary-workbrief.d.ts +144 -0
- package/dist/src/services/secretary-workbrief.d.ts.map +1 -0
- package/dist/src/services/secretary-workbrief.js +315 -0
- package/dist/src/services/secretary-workbrief.js.map +1 -0
- package/dist/src/services/secretary-worktier.d.ts +118 -0
- package/dist/src/services/secretary-worktier.d.ts.map +1 -0
- package/dist/src/services/secretary-worktier.js +157 -0
- package/dist/src/services/secretary-worktier.js.map +1 -0
- package/dist/src/services/skill-bundle/generator.d.ts +3 -0
- package/dist/src/services/skill-bundle/generator.d.ts.map +1 -1
- package/dist/src/services/skill-bundle/generator.js +19 -0
- package/dist/src/services/skill-bundle/generator.js.map +1 -1
- package/dist/src/services/specialist-runner.d.ts +36 -0
- package/dist/src/services/specialist-runner.d.ts.map +1 -0
- package/dist/src/services/specialist-runner.js +91 -0
- package/dist/src/services/specialist-runner.js.map +1 -0
- package/dist/src/services/specialist.d.ts +9 -0
- package/dist/src/services/specialist.d.ts.map +1 -1
- package/dist/src/services/specialist.js +42 -0
- package/dist/src/services/specialist.js.map +1 -1
- package/dist/src/services/structure-overview.d.ts +13 -0
- package/dist/src/services/structure-overview.d.ts.map +1 -1
- package/dist/src/services/structure-overview.js +34 -11
- package/dist/src/services/structure-overview.js.map +1 -1
- package/dist/src/services/system-agent-responder.d.ts +36 -0
- package/dist/src/services/system-agent-responder.d.ts.map +1 -0
- package/dist/src/services/system-agent-responder.js +107 -0
- package/dist/src/services/system-agent-responder.js.map +1 -0
- package/dist/src/services/system-agent.d.ts +34 -1
- package/dist/src/services/system-agent.d.ts.map +1 -1
- package/dist/src/services/system-agent.js +73 -0
- package/dist/src/services/system-agent.js.map +1 -1
- package/dist/src/storage/interface.d.ts +33 -0
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/interface.js.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +37 -0
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +132 -12
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +23 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +60 -8
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts +29 -1
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.js +109 -10
- package/dist/src/storage/providers/sqlite/repos/memory.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts +3 -0
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +64 -9
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/app.repository.d.ts +15 -0
- package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/memory.repository.d.ts +41 -1
- package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/organism.repository.d.ts +2 -1
- package/dist/src/storage/repositories/organism.repository.d.ts.map +1 -1
- package/dist/static/app-catalog.html +469 -122
- package/package.json +2 -1
- package/prisma/schema.postgres.prisma +10 -0
- package/prisma/schema.prisma +12 -0
|
@@ -4,10 +4,16 @@
|
|
|
4
4
|
* main component focused on state + logic (and under the file-size limit). Each export is a PURE render
|
|
5
5
|
* function taking a props bag — no hooks, no state — so the view owns all state/handlers and passes
|
|
6
6
|
* them in. Cards: contextSwitcher · hirePanel · chatCard · findCard · noteCard · decisionsCard ·
|
|
7
|
-
* brainCard · operatingCard · historyCard · metaCard. See views/secretary.js + docs/plans/2026-06-23-secretary-feature.md.
|
|
7
|
+
* brainCard · operatingCard · historyCard · metaCard · whatsNextCard. See views/secretary.js + docs/plans/2026-06-23-secretary-feature.md.
|
|
8
8
|
* @structure one exported render function per card (props in → htm out)
|
|
9
9
|
* @usage import { chatCard, findCard, ... } from '/views/secretary/cards.js'; ... ${chatCard({...})}
|
|
10
10
|
* @version-history
|
|
11
|
+
* v0.10.0 — 2026-06-28 — G7: the delegate control gains a workflow picker (run an Agent Workflow chaining specialists).
|
|
12
|
+
* v0.9.0 — 2026-06-28 — G10: feedCard groups entries by day (Today / Yesterday / date) with per-day counts.
|
|
13
|
+
* v0.8.0 — 2026-06-28 — B4: routineStepRow gains the delegate control (pick a target agent → create an
|
|
14
|
+
* agent task) + a "Check result" action on delegated steps.
|
|
15
|
+
* v0.7.0 — 2026-06-27 — B2: replace guidedPlanCard with whatsNextCard (Routine propose/advance,
|
|
16
|
+
* band-gated steps + per-step approve/run); guided-plan flow folded into "What's next".
|
|
11
17
|
* v0.6.0 — 2026-06-24 — P3-A: chatCard gains a doc/image attach control (📎) + an in-flight /
|
|
12
18
|
* filed status line, driven by the intake hook's handleAttach.
|
|
13
19
|
* v0.5.0 — 2026-06-24 — P2-E: noteCard shows the cross-context route banner (auto-route to a
|
|
@@ -22,17 +28,17 @@ import { h } from 'preact';
|
|
|
22
28
|
import htm from 'htm';
|
|
23
29
|
const html = htm.bind(h);
|
|
24
30
|
import { t } from '/js/i18n.js';
|
|
25
|
-
import { escHtml } from '/js/utils.js';
|
|
26
31
|
import { CopyButton } from '/components/CopyButton.js';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
32
|
+
import { Markdown } from '/components/Markdown.js';
|
|
33
|
+
import { SECRETARY_CAPABILITIES, BANDS, autonomyLevelOf } from '/js/services/secretary-policy.js';
|
|
34
|
+
import { buildInterviewPrompt, groupFeedByDay } from '/js/services/secretary-helpers.js';
|
|
29
35
|
|
|
30
36
|
/** Context "hats" switcher chips + add. */
|
|
31
37
|
export function contextSwitcher(p) {
|
|
32
38
|
return html`
|
|
33
39
|
<div class="sec-ctx-bar">
|
|
34
40
|
${p.contexts.map((c) => html`
|
|
35
|
-
<button class="sec-ctx-chip ${c.id === p.activeId ? 'active' : ''}" key=${c.id} onClick=${() => p.switchContext(c.id)}>${
|
|
41
|
+
<button class="sec-ctx-chip ${c.id === p.activeId ? 'active' : ''}" key=${c.id} onClick=${() => p.switchContext(c.id)}>${(c.name)}</button>`)}
|
|
36
42
|
<button class="sec-ctx-add" title=${t('secretary.addContext')} onClick=${p.openAdd}>+</button>
|
|
37
43
|
</div>`;
|
|
38
44
|
}
|
|
@@ -48,8 +54,8 @@ export function hirePanel(p) {
|
|
|
48
54
|
<p class="sec-desc">${t('secretary.hireIntro')}</p>
|
|
49
55
|
<div class="sec-opt">
|
|
50
56
|
<div class="sec-opt-h">${t('secretary.optionA')}</div>
|
|
51
|
-
<div class="sec-prompt-box">${buildInterviewPrompt(p.owner)}</div>
|
|
52
|
-
<${CopyButton} text=${buildInterviewPrompt(p.owner)} className="btn-outline btn-sm" label=${t('secretary.copyPrompt')} copiedLabel=${'✓ ' + t('secretary.copied')} />
|
|
57
|
+
<div class="sec-prompt-box">${buildInterviewPrompt(p.owner, p.current)}</div>
|
|
58
|
+
<${CopyButton} text=${buildInterviewPrompt(p.owner, p.current)} className="btn-outline btn-sm" label=${t('secretary.copyPrompt')} copiedLabel=${'✓ ' + t('secretary.copied')} />
|
|
53
59
|
</div>
|
|
54
60
|
<div class="sec-opt">
|
|
55
61
|
<div class="sec-opt-h">${t('secretary.optionB')}</div>
|
|
@@ -69,21 +75,21 @@ export function chatCard(p) {
|
|
|
69
75
|
const canAttach = typeof p.onAttach === 'function' && p.canAttach !== false;
|
|
70
76
|
return html`
|
|
71
77
|
<section class="sec-card sec-chat">
|
|
72
|
-
<h2 class="sec-h2">${t('secretary.chatTitle')} · ${
|
|
78
|
+
<h2 class="sec-h2">${t('secretary.chatTitle')} · ${(p.activeName)}</h2>
|
|
73
79
|
<div class="sec-chat-log">
|
|
74
80
|
${p.chat.length === 0
|
|
75
81
|
? html`<div class="sec-hint">${t('secretary.chatEmpty')}</div>`
|
|
76
|
-
: p.chat.map((m, i) => html`<div class="sec-msg sec-msg-${m.role}" key=${i}>${
|
|
82
|
+
: p.chat.map((m, i) => html`<div class="sec-msg sec-msg-${m.role}" key=${i}>${(m.content)}</div>`)}
|
|
77
83
|
${p.chatSending ? html`<div class="sec-msg sec-msg-assistant sec-msg-pending">…</div>` : null}
|
|
78
84
|
</div>
|
|
79
85
|
${p.routeSuggestion ? html`
|
|
80
86
|
<div class="sec-route-hint">
|
|
81
|
-
<span>${t('secretary.routeSuggest')} <strong>${
|
|
87
|
+
<span>${t('secretary.routeSuggest')} <strong>${(p.routeSuggestion.name)}</strong></span>
|
|
82
88
|
<button class="btn-ghost btn-sm" onClick=${() => p.switchContext(p.routeSuggestion.id)}>${t('secretary.routeSwitch')}</button>
|
|
83
89
|
</div>` : null}
|
|
84
90
|
${canAttach && p.attaching ? html`<div class="sec-hint sec-attach-status">${t('secretary.attaching')}</div>` : null}
|
|
85
91
|
${canAttach && !p.attaching && p.attachResult ? html`
|
|
86
|
-
<div class="sec-route-hint"><span>${t('secretary.attachFiled')} <strong>${
|
|
92
|
+
<div class="sec-route-hint"><span>${t('secretary.attachFiled')} <strong>${(p.attachResult.wsName)}</strong>${p.attachResult.name ? html` — ${(p.attachResult.name)}` : null}</span></div>` : null}
|
|
87
93
|
<div class="sec-chat-input">
|
|
88
94
|
<textarea rows="2" placeholder=${t('secretary.chatPlaceholder')} value=${p.chatInput}
|
|
89
95
|
onInput=${(e) => p.setChatInput(e.target.value)}
|
|
@@ -123,10 +129,10 @@ export function findCard(p) {
|
|
|
123
129
|
? html`<div class="sec-hint">${t('secretary.findEmpty')}</div>`
|
|
124
130
|
: p.findResults.map((e, i) => html`
|
|
125
131
|
<div class="sec-find-row" key=${i}>
|
|
126
|
-
<span class="sec-find-type">${
|
|
132
|
+
<span class="sec-find-type">${(e.type)}</span>
|
|
127
133
|
<div class="sec-find-main">
|
|
128
|
-
<div class="sec-find-title">${e.url ? html`<a href=${e.url} target="_blank" rel="noreferrer">${
|
|
129
|
-
${e.description ? html`<div class="sec-find-desc">${
|
|
134
|
+
<div class="sec-find-title">${e.url ? html`<a href=${e.url} target="_blank" rel="noreferrer">${(e.title)}</a>` : (e.title)}</div>
|
|
135
|
+
${e.description ? html`<div class="sec-find-desc">${(String(e.description).slice(0, 160))}</div>` : null}
|
|
130
136
|
</div>
|
|
131
137
|
</div>`)}
|
|
132
138
|
</div>`}
|
|
@@ -142,14 +148,14 @@ export function noteCard(p) {
|
|
|
142
148
|
<textarea class="sec-paste" rows="3" placeholder=${t('secretary.notePlaceholder')} value=${p.noteText} onInput=${(e) => p.setNoteText(e.target.value)}></textarea>
|
|
143
149
|
${p.route && p.route.confidence === 'high' ? html`
|
|
144
150
|
<div class="sec-route-hint">
|
|
145
|
-
<span>${t('secretary.routeBelongs')} <strong>${
|
|
151
|
+
<span>${t('secretary.routeBelongs')} <strong>${(p.route.name)}</strong></span>
|
|
146
152
|
<button class="btn-outline btn-sm" disabled=${p.noteSaving} onClick=${p.autoRouteNote}>${t('secretary.routeFileThere')}</button>
|
|
147
153
|
</div>` : p.route && p.route.confidence === 'low' ? html`
|
|
148
154
|
<div class="sec-route-hint"><span class="sec-hint">${t('secretary.routeUnsure')}</span></div>` : null}
|
|
149
155
|
<div class="sec-note-bar">
|
|
150
156
|
<label class="sec-hint">${t('secretary.noteInto')}</label>
|
|
151
157
|
<select class="sec-band" value=${p.effectiveWsId} onChange=${(e) => p.setNoteWsId(e.target.value)}>
|
|
152
|
-
${p.wsList.map((w) => html`<option value=${w.id} selected=${p.effectiveWsId === w.id}>${
|
|
158
|
+
${p.wsList.map((w) => html`<option value=${w.id} selected=${p.effectiveWsId === w.id}>${(w.name)}</option>`)}
|
|
153
159
|
</select>
|
|
154
160
|
<button class="btn-primary" disabled=${!p.noteText.trim() || p.noteSaving} onClick=${p.saveNote}>${p.noteSaving ? t('secretary.noteSaving') : t('secretary.noteSave')}</button>
|
|
155
161
|
${p.wsList.length >= 2 ? html`<button class="btn-outline btn-sm" disabled=${!p.noteText.trim() || p.noteSaving} onClick=${p.askDecision} title=${t('secretary.askInInboxHint')}>${t('secretary.askInInbox')}</button>` : null}
|
|
@@ -167,9 +173,9 @@ export function decisionsCard(p) {
|
|
|
167
173
|
const dec = p.pendingDecisions[pid];
|
|
168
174
|
const answer = p.decisionAnswers[pid];
|
|
169
175
|
return html`<li class="sec-hist-row" key=${pid}>
|
|
170
|
-
<span class="sec-hist-purpose">${
|
|
176
|
+
<span class="sec-hist-purpose">${((dec.body || dec.text || dec.question || '').slice(0, 60))}</span>
|
|
171
177
|
${answer
|
|
172
|
-
? html`<button class="btn-primary btn-sm" onClick=${() => p.applyDecision(pid)}>${t('secretary.decisionApply')}: ${
|
|
178
|
+
? html`<button class="btn-primary btn-sm" onClick=${() => p.applyDecision(pid)}>${t('secretary.decisionApply')}: ${(answer)}</button>`
|
|
173
179
|
: html`<span class="sec-hint">${t('secretary.decisionAwaiting')}</span>`}
|
|
174
180
|
<button class="btn-ghost btn-sm" onClick=${() => p.dismissDecision(pid)}>${t('secretary.cancel')}</button>
|
|
175
181
|
</li>`;
|
|
@@ -182,28 +188,61 @@ export function decisionsCard(p) {
|
|
|
182
188
|
export function brainCard(p) {
|
|
183
189
|
const brain = p.brain;
|
|
184
190
|
const active = p.active;
|
|
191
|
+
const d = p.brainDraft; // C2: when set, the brain is in inline-edit mode
|
|
185
192
|
return html`
|
|
186
193
|
<section class="sec-card">
|
|
187
194
|
<div class="sec-card-head">
|
|
188
195
|
<div class="sec-status"><span class="sec-dot"></span> ${t('secretary.hiredStatus')}</div>
|
|
189
|
-
|
|
196
|
+
${!d ? html`<div class="sec-brain-actions">
|
|
197
|
+
<button class="btn-ghost btn-sm" onClick=${p.startBrainEdit}>${t('secretary.editBrain')}</button>
|
|
198
|
+
<button class="btn-ghost btn-sm" onClick=${p.openEdit}>${t('secretary.rerun')}</button>
|
|
199
|
+
</div>` : null}
|
|
190
200
|
</div>
|
|
191
201
|
<h2 class="sec-h2">${t('secretary.brain')}</h2>
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
${d ? html`
|
|
203
|
+
<textarea class="sec-input" rows="3" value=${d.purpose} onInput=${(e) => p.setBrainDraft({ ...d, purpose: e.target.value })}></textarea>
|
|
204
|
+
<div class="sec-h3">${t('secretary.rules')}</div>
|
|
205
|
+
<ul class="sec-rule-edit">
|
|
206
|
+
${d.rules.map((r, i) => html`
|
|
207
|
+
<li class="sec-rule-row" key=${i}>
|
|
208
|
+
<input class="sec-input" value=${r.description} onInput=${(e) => p.setBrainDraft({ ...d, rules: d.rules.map((x, j) => (j === i ? { ...x, description: e.target.value } : x)) })} />
|
|
209
|
+
<button class="btn-ghost btn-sm" title=${t('secretary.remove')} onClick=${() => p.setBrainDraft({ ...d, rules: d.rules.filter((_, j) => j !== i) })}>✕</button>
|
|
210
|
+
</li>`)}
|
|
211
|
+
</ul>
|
|
212
|
+
<button class="btn-ghost btn-sm" onClick=${() => p.setBrainDraft({ ...d, rules: [...d.rules, { id: '', description: '' }] })}>+ ${t('secretary.addRule')}</button>
|
|
213
|
+
<div class="sec-actions">
|
|
214
|
+
<button class="btn-ghost btn-sm" onClick=${p.cancelBrainEdit}>${t('secretary.cancel')}</button>
|
|
215
|
+
<button class="btn-primary btn-sm" disabled=${p.savingBrain} onClick=${p.saveBrain}>${p.savingBrain ? t('secretary.saving') : t('secretary.save')}</button>
|
|
216
|
+
</div>`
|
|
217
|
+
: html`
|
|
218
|
+
<p class="sec-purpose">${(brain.purpose)}</p>
|
|
219
|
+
${Array.isArray(brain.rules) && brain.rules.length > 0 && html`<ul class="sec-rules">${brain.rules.map((r) => html`<li key=${r.id}>${(r.description)}</li>`)}</ul>`}`}
|
|
194
220
|
${active.organismName && html`
|
|
195
221
|
<h2 class="sec-h2">${t('secretary.selfOrganism')}</h2>
|
|
196
|
-
<p class="sec-orgname">🗂 ${
|
|
197
|
-
${Array.isArray(active.workspaces) && html`<ul class="sec-ws">${active.workspaces.map((w, i) => html`<li key=${i}><strong>${
|
|
222
|
+
<p class="sec-orgname">🗂 ${(active.organismName)}</p>
|
|
223
|
+
${Array.isArray(active.workspaces) && html`<ul class="sec-ws">${active.workspaces.map((w, i) => html`<li key=${i}><strong>${(w.name)}</strong>${w.purpose ? html` — ${(w.purpose)}` : null}</li>`)}</ul>`}`}
|
|
198
224
|
</section>`;
|
|
199
225
|
}
|
|
200
226
|
|
|
201
227
|
/** Operating model: stop-spending + daily budget + per-capability autonomy bands. */
|
|
202
228
|
export function operatingCard(p) {
|
|
203
229
|
const policy = p.policy;
|
|
230
|
+
const level = autonomyLevelOf(policy.bands); // 'suggest' | 'assist' — the single toggle's state
|
|
204
231
|
return html`
|
|
205
232
|
<section class="sec-card">
|
|
206
233
|
<h2 class="sec-h2">${t('secretary.howIWork')}</h2>
|
|
234
|
+
|
|
235
|
+
${/* ONE autonomy toggle (collapses the per-capability band sprawl). Heavy work is always a Work
|
|
236
|
+
Brief a Builder executes — never something the cheap Secretary does on its own. */ ''}
|
|
237
|
+
<div class="sec-autonomy">
|
|
238
|
+
${[['suggest', 'secretary.autonomy.suggest', 'secretary.autonomy.suggestHint'],
|
|
239
|
+
['assist', 'secretary.autonomy.assist', 'secretary.autonomy.assistHint']].map(([val, label, hint]) => html`
|
|
240
|
+
<label class=${'sec-auto-opt' + (level === val ? ' sec-auto-opt--on' : '')} key=${val}>
|
|
241
|
+
<input type="radio" name="sec-autonomy" checked=${level === val} onChange=${() => p.setAutonomy(val)} />
|
|
242
|
+
<span><strong>${t(label)}</strong><br/><span class="sec-hint">${t(hint)}</span></span>
|
|
243
|
+
</label>`)}
|
|
244
|
+
</div>
|
|
245
|
+
|
|
207
246
|
<label class="sec-stop ${policy.stopSpending ? 'on' : ''}">
|
|
208
247
|
<input type="checkbox" checked=${policy.stopSpending} onChange=${p.toggleStop} />
|
|
209
248
|
<span><strong>${t('secretary.stopSpending')}</strong><br/><span class="sec-hint">${t('secretary.stopSpendingHint')}</span></span>
|
|
@@ -213,18 +252,24 @@ export function operatingCard(p) {
|
|
|
213
252
|
<input type="number" min="0" class="sec-budget-in" value=${policy.dailyMorselBudget == null ? '' : policy.dailyMorselBudget} placeholder=${t('secretary.noLimit')} onChange=${(e) => p.setBudget(e.target.value)} />
|
|
214
253
|
<span class="sec-hint">${t('secretary.dailyBudgetHint')}</span>
|
|
215
254
|
</div>
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
255
|
+
|
|
256
|
+
${/* Per-capability bands are still here for power users, tucked behind an Advanced disclosure so the
|
|
257
|
+
default surface is just the one toggle above. */ ''}
|
|
258
|
+
<details class="sec-adv">
|
|
259
|
+
<summary>${t('secretary.advancedBands')}</summary>
|
|
260
|
+
<p class="sec-hint sec-bands-note">${t('secretary.bandsNote')}</p>
|
|
261
|
+
<ul class="sec-caps">
|
|
262
|
+
${SECRETARY_CAPABILITIES.map((c) => html`
|
|
263
|
+
<li class="sec-cap" key=${c.id}>
|
|
264
|
+
<span class="sec-cap-label">${t('secretary.cap.' + c.id)}${c.costs ? html`<span class="sec-cap-tag">${t('secretary.capCosts')}</span>` : null}</span>
|
|
265
|
+
${c.enterprise
|
|
266
|
+
? html`<span class="sec-cap-locked sec-cap-ent">${t('secretary.enterprise')}</span>`
|
|
267
|
+
: c.locked
|
|
268
|
+
? html`<span class="sec-cap-locked">${t('secretary.band.' + policy.bands[c.id])} · ${t('secretary.locked')}</span>`
|
|
269
|
+
: html`<select class="sec-band" value=${policy.bands[c.id]} onChange=${(e) => p.setBand(c.id, e.target.value)}>${BANDS.map((b) => html`<option value=${b} selected=${policy.bands[c.id] === b}>${t('secretary.band.' + b)}</option>`)}</select>`}
|
|
270
|
+
</li>`)}
|
|
271
|
+
</ul>
|
|
272
|
+
</details>
|
|
228
273
|
</section>`;
|
|
229
274
|
}
|
|
230
275
|
|
|
@@ -236,58 +281,148 @@ export function historyCard(p) {
|
|
|
236
281
|
<ul class="sec-hist">
|
|
237
282
|
${p.brainHistory.map((snap, i) => html`
|
|
238
283
|
<li class="sec-hist-row" key=${i}>
|
|
239
|
-
<span class="sec-hist-purpose">${
|
|
284
|
+
<span class="sec-hist-purpose">${((snap.purpose || '').slice(0, 80))}</span>
|
|
240
285
|
<button class="btn-ghost btn-sm" disabled=${p.applying} onClick=${() => p.restore(snap)}>${t('secretary.restore')}</button>
|
|
241
286
|
</li>`)}
|
|
242
287
|
</ul>
|
|
243
288
|
</section>`;
|
|
244
289
|
}
|
|
245
290
|
|
|
246
|
-
/**
|
|
247
|
-
|
|
291
|
+
/** A single Routine step row (B2 + B4): capability + band + summary + result, with the approve/run/delegate control. */
|
|
292
|
+
function routineStepRow(p, r, s) {
|
|
293
|
+
const next = p.nextPendingStep(r);
|
|
294
|
+
const isNext = next && next.id === s.id;
|
|
295
|
+
const busy = p.busyStepId === s.id;
|
|
296
|
+
const runLabel = s.band === 'off' ? t('secretary.next.skip') : s.band === 'act' ? t('secretary.next.run') : t('secretary.next.approve');
|
|
297
|
+
const isDelegate = s.capability === 'delegate';
|
|
298
|
+
const agents = p.agents || [];
|
|
299
|
+
const workflows = p.workflows || [];
|
|
300
|
+
// Unblur the delegation target by ROLE: node-local Specialists vs connected big-AI Builders. The Secretary
|
|
301
|
+
// (the watcher) is never a delegation target. Same handler/value (agent name) — the optgroups just label
|
|
302
|
+
// which kind of agent each is, so "pick a specialist" no longer lumps Builders + specialists together.
|
|
303
|
+
const isSpecialist = (a) => (a.tags || []).includes('system:specialist');
|
|
304
|
+
const isSecretary = (a) => (a.tags || []).includes('system:secretary') || a.name === 'secretary';
|
|
305
|
+
const specialistAgents = agents.filter((a) => isSpecialist(a));
|
|
306
|
+
const builderAgents = agents.filter((a) => !isSpecialist(a) && !isSecretary(a));
|
|
307
|
+
// B4: delegate to one agent (agent task) · G7: OR run an Agent Workflow chaining specialists.
|
|
308
|
+
const delegateControl = html`
|
|
309
|
+
<div class="sec-delegate">
|
|
310
|
+
${(specialistAgents.length + builderAgents.length) > 0 ? html`
|
|
311
|
+
<select class="sec-band" value=${p.delegateAgent} onChange=${(e) => p.setDelegateAgent(e.target.value)}>
|
|
312
|
+
<option value="" selected=${!p.delegateAgent}>${t('secretary.next.delegatePick')}</option>
|
|
313
|
+
${specialistAgents.length ? html`<optgroup label=${t('secretary.next.delegateSpecialists')}>
|
|
314
|
+
${specialistAgents.map((a) => html`<option value=${a.name} selected=${p.delegateAgent === a.name}>${(a.name)}</option>`)}
|
|
315
|
+
</optgroup>` : null}
|
|
316
|
+
${builderAgents.length ? html`<optgroup label=${t('secretary.next.delegateBuilders')}>
|
|
317
|
+
${builderAgents.map((a) => html`<option value=${a.name} selected=${p.delegateAgent === a.name}>${(a.name)}</option>`)}
|
|
318
|
+
</optgroup>` : null}
|
|
319
|
+
</select>
|
|
320
|
+
<button class="btn-primary btn-sm" disabled=${busy || !p.delegateAgent} onClick=${() => p.approveStep(r, s, { agentName: p.delegateAgent })}>${busy ? t('secretary.next.running') : t('secretary.next.delegateGo')}</button>` : null}
|
|
321
|
+
${workflows.length > 0 ? html`
|
|
322
|
+
<select class="sec-band" value=${p.delegateWorkflow} onChange=${(e) => p.setDelegateWorkflow(e.target.value)}>
|
|
323
|
+
<option value="" selected=${!p.delegateWorkflow}>${t('secretary.next.delegateWorkflowPick')}</option>
|
|
324
|
+
${workflows.map((w) => html`<option value=${w.id} selected=${p.delegateWorkflow === w.id}>${((w.title && (w.title.en_US || w.title)) || w.id)}</option>`)}
|
|
325
|
+
</select>
|
|
326
|
+
<button class="btn-outline btn-sm" disabled=${busy || !p.delegateWorkflow} onClick=${() => p.approveStep(r, s, { workflowId: p.delegateWorkflow, workflowName: (workflows.find((w) => w.id === p.delegateWorkflow) || {}).title?.en_US })}>${busy ? t('secretary.next.running') : t('secretary.next.delegateWorkflowGo')}</button>` : null}
|
|
327
|
+
${p.onDesignWorkflow ? html`<button class="btn-ghost btn-sm" disabled=${busy} title=${t('secretary.wf.title')} onClick=${() => p.onDesignWorkflow(s)}>${t('secretary.next.delegateDesignWf')}</button>` : null}
|
|
328
|
+
${agents.length === 0 && workflows.length === 0 && !p.onDesignWorkflow ? html`<span class="sec-hint">${t('secretary.next.delegateNoAgents')}</span>` : null}
|
|
329
|
+
</div>`;
|
|
330
|
+
return html`
|
|
331
|
+
<li class="sec-step-row ${s.status}" key=${s.id}>
|
|
332
|
+
<div class="sec-step-main">
|
|
333
|
+
<div class="sec-step-tags">
|
|
334
|
+
<span class="sec-step-cap">${t('secretary.cap.' + s.capability)}</span>
|
|
335
|
+
<span class="sec-band-tag band-${s.band}">${t('secretary.band.' + s.band)}</span>
|
|
336
|
+
</div>
|
|
337
|
+
<div class="sec-step-summary">${(s.summary)}</div>
|
|
338
|
+
${s.result ? html`<div class="sec-hint">→ ${(s.result.summary)}</div>` : null}
|
|
339
|
+
${s.status === 'delegated' && s.result && (s.result.taskId || s.result.runId) ? html`
|
|
340
|
+
<button class="btn-ghost btn-sm" disabled=${p.checkingStepId === s.id} onClick=${() => p.checkDelegateResult(r, s)}>${p.checkingStepId === s.id ? t('secretary.next.running') : t('secretary.next.checkResult')}</button>` : null}
|
|
341
|
+
</div>
|
|
342
|
+
${s.status === 'pending'
|
|
343
|
+
? (isNext
|
|
344
|
+
? (isDelegate
|
|
345
|
+
? delegateControl
|
|
346
|
+
: html`<button class="btn-primary btn-sm" disabled=${busy} onClick=${() => p.approveStep(r, s)}>${busy ? t('secretary.next.running') : runLabel}</button>`)
|
|
347
|
+
: html`<span class="sec-hint">${t('secretary.next.queued')}</span>`)
|
|
348
|
+
: html`<span class="sec-step-status sec-${s.status}">${t('secretary.next.status.' + s.status)}</span>`}
|
|
349
|
+
</li>`;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** B2 "What's next": propose a NEW routine from a goal, or walk the selected one step-by-step (band-gated). */
|
|
353
|
+
export function whatsNextCard(p) {
|
|
354
|
+
const r = p.selected;
|
|
248
355
|
return html`
|
|
249
|
-
<section class="sec-card sec-
|
|
250
|
-
<h2 class="sec-h2">${t('secretary.
|
|
251
|
-
<p class="sec-hint">${t('secretary.
|
|
252
|
-
${!
|
|
253
|
-
<
|
|
356
|
+
<section class="sec-card sec-next">
|
|
357
|
+
<h2 class="sec-h2">${t('secretary.next.cardTitle')}</h2>
|
|
358
|
+
<p class="sec-hint">${t('secretary.next.hint')}</p>
|
|
359
|
+
${!r ? html`
|
|
360
|
+
<p class="sec-hint">${t('secretary.next.explain')}</p>
|
|
361
|
+
${p.actionItems && p.actionItems.length ? html`<div class="sec-next-followups">↑ ${t('secretary.next.followups', { n: p.actionItems.length })}</div>` : null}
|
|
362
|
+
${p.activeRoutines && p.activeRoutines.length ? html`
|
|
363
|
+
<div class="sec-h3">${t('secretary.next.continueTitle')}</div>
|
|
364
|
+
<ul class="sec-routine-list">
|
|
365
|
+
${p.activeRoutines.map((rt) => {
|
|
366
|
+
const ns = p.nextPendingStep(rt);
|
|
367
|
+
return html`
|
|
368
|
+
<li class="sec-routine-row" key=${rt.id}>
|
|
369
|
+
<div class="sec-routine-main">
|
|
370
|
+
<div class="sec-routine-title">${(rt.title)}</div>
|
|
371
|
+
<div class="sec-hint">${ns ? `${t('secretary.next.nextStep')}: ${ns.summary}` : t('secretary.next.allSettled')}</div>
|
|
372
|
+
</div>
|
|
373
|
+
<button class="btn-outline btn-sm" onClick=${() => p.advance(rt)}>${t('secretary.next.advance')}</button>
|
|
374
|
+
</li>`;
|
|
375
|
+
})}
|
|
376
|
+
</ul>` : null}
|
|
377
|
+
<div class="sec-h3">${t('secretary.next.startNewTitle')}</div>
|
|
378
|
+
<textarea class="sec-paste" rows="2" placeholder=${t('secretary.next.placeholder')} value=${p.goal} onInput=${(e) => p.setGoal(e.target.value)}></textarea>
|
|
254
379
|
<div class="sec-actions">
|
|
255
|
-
<button class="btn-primary" disabled=${!p.goal.trim() || p.
|
|
256
|
-
</div>` :
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
<button class="btn-ghost btn-sm" onClick=${p.cancelPlan}>${t('secretary.cancel')}</button>
|
|
265
|
-
<button class="btn-primary" disabled=${p.running} onClick=${p.runPlan}>${p.running ? t('secretary.plan.running') : t('secretary.plan.approve')}</button>
|
|
380
|
+
<button class="btn-primary" disabled=${!p.goal.trim() || p.proposing} onClick=${p.proposeRoutine}>${p.proposing ? t('secretary.next.proposing') : t('secretary.next.propose')}</button>
|
|
381
|
+
</div>` : html`
|
|
382
|
+
<div class="sec-routine">
|
|
383
|
+
<div class="sec-routine-head">
|
|
384
|
+
<div>
|
|
385
|
+
<div class="sec-routine-title">${(r.title)}</div>
|
|
386
|
+
${r.purpose ? html`<div class="sec-hint">${(r.purpose)}</div>` : null}
|
|
387
|
+
</div>
|
|
388
|
+
${r.status === 'done' ? html`<span class="sec-step-status sec-done">${t('secretary.next.status.done')}</span>` : null}
|
|
266
389
|
</div>
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
390
|
+
<div class="sec-routine-cadence">
|
|
391
|
+
<label class="sec-hint">${t('secretary.next.repeats')}</label>
|
|
392
|
+
<select class="sec-band" value=${r.cadence || ''} onChange=${(e) => p.setRoutineCadence(r, e.target.value)}>
|
|
393
|
+
<option value="" selected=${!r.cadence}>${t('secretary.next.cadence.none')}</option>
|
|
394
|
+
<option value="daily" selected=${r.cadence === 'daily'}>${t('secretary.next.cadence.daily')}</option>
|
|
395
|
+
<option value="weekly" selected=${r.cadence === 'weekly'}>${t('secretary.next.cadence.weekly')}</option>
|
|
396
|
+
</select>
|
|
397
|
+
${r.cadence && r.nextRunAt ? html`<span class="sec-hint">${t('secretary.next.nextRun')}: ${new Date(r.nextRunAt).toLocaleDateString()}</span>` : null}
|
|
398
|
+
</div>
|
|
399
|
+
<ul class="sec-step-list">${r.steps.map((s) => routineStepRow(p, r, s))}</ul>
|
|
400
|
+
<div class="sec-actions sec-routine-actions">
|
|
401
|
+
<button class="btn-ghost btn-sm" onClick=${() => p.setSelectedId(null)}>${t('secretary.next.startNew')}</button>
|
|
402
|
+
<button class="btn-ghost btn-sm" onClick=${() => p.deleteRoutine(r)}>${t('secretary.next.discard')}</button>
|
|
403
|
+
</div>
|
|
404
|
+
</div>`}
|
|
275
405
|
</section>`;
|
|
276
406
|
}
|
|
277
407
|
|
|
278
|
-
/** Home feed (Phase 4): what the Secretary did on its own (
|
|
408
|
+
/** Home feed (Phase 4 + G10): what the Secretary did on its own, grouped by day (today + previous days). */
|
|
279
409
|
export function feedCard(p) {
|
|
280
410
|
return html`
|
|
281
411
|
<section class="sec-card sec-feed">
|
|
282
412
|
<h2 class="sec-h2">${t('secretary.feed.title')}</h2>
|
|
283
413
|
${p.feed.length === 0
|
|
284
414
|
? html`<div class="sec-hint">${t('secretary.feed.empty')}</div>`
|
|
285
|
-
: html
|
|
286
|
-
|
|
287
|
-
<div class="sec-feed-
|
|
288
|
-
<
|
|
289
|
-
|
|
290
|
-
|
|
415
|
+
: groupFeedByDay(p.feed).map((g) => html`
|
|
416
|
+
<div class="sec-feed-day" key=${g.key}>
|
|
417
|
+
<div class="sec-feed-day-head">${(g.label)} <span class="sec-feed-day-count">${g.items.length}</span></div>
|
|
418
|
+
<ul class="sec-feed-list">
|
|
419
|
+
${g.items.map((it, i) => html`<li class="sec-feed-item" key=${it.id || i}>
|
|
420
|
+
<div class="sec-feed-meta">${it.contextName ? (it.contextName) + ' · ' : ''}${it.ts ? new Date(it.ts).toLocaleTimeString() : ''}</div>
|
|
421
|
+
<div class="sec-feed-text"><${Markdown} text=${it.text || ''} /></div>
|
|
422
|
+
${it.href ? html`<a class="sec-feed-link" href=${it.href} target="_blank" rel="noopener">${t('secretary.next.openResult')} ↗</a>` : null}
|
|
423
|
+
</li>`)}
|
|
424
|
+
</ul>
|
|
425
|
+
</div>`)}
|
|
291
426
|
</section>`;
|
|
292
427
|
}
|
|
293
428
|
|
|
@@ -303,8 +438,8 @@ export function automationCard(p) {
|
|
|
303
438
|
: html`
|
|
304
439
|
<div class="sec-auto-row">
|
|
305
440
|
<div>
|
|
306
|
-
<div><strong>${
|
|
307
|
-
<div class="sec-hint">${t('secretary.auto.nextRun')}: ${s.nextRunAt ? new Date(s.nextRunAt).toLocaleString() : '—'}${s.cron ? ' · ' +
|
|
441
|
+
<div><strong>${(s.displayName || t('secretary.auto.scheduleName'))}</strong>${s.enabled ? null : html` <span class="sec-hint">(${t('secretary.auto.paused')})</span>`}</div>
|
|
442
|
+
<div class="sec-hint">${t('secretary.auto.nextRun')}: ${s.nextRunAt ? new Date(s.nextRunAt).toLocaleString() : '—'}${s.cron ? ' · ' + (s.cron) : ''}</div>
|
|
308
443
|
${p.budgetInfo ? html`<div class="sec-hint">${t('secretary.auto.budgetLeft')}: ${p.budgetInfo.remaining} / ${p.budgetInfo.budget}</div>` : null}
|
|
309
444
|
</div>
|
|
310
445
|
<div class="sec-auto-actions">
|
|
@@ -335,8 +470,8 @@ export function goalsCard(p) {
|
|
|
335
470
|
: html`<ul class="sec-goal-list">
|
|
336
471
|
${p.goals.map((g) => html`<li class="sec-goal-row ${g.status === 'done' ? 'done' : ''}" key=${g.id}>
|
|
337
472
|
<div class="sec-goal-main">
|
|
338
|
-
<div class="sec-goal-title">${
|
|
339
|
-
${g.why ? html`<div class="sec-hint">${
|
|
473
|
+
<div class="sec-goal-title">${(g.title)}</div>
|
|
474
|
+
${g.why ? html`<div class="sec-hint">${(g.why)}</div>` : null}
|
|
340
475
|
</div>
|
|
341
476
|
<button class="btn-ghost btn-sm" onClick=${() => p.completeGoal(g)}>${g.status === 'done' ? t('secretary.learn.reopen') : t('secretary.learn.done')}</button>
|
|
342
477
|
<button class="btn-ghost btn-sm" onClick=${() => p.deleteGoal(g)}>✕</button>
|
|
@@ -375,7 +510,7 @@ export function decisionLogCard(p) {
|
|
|
375
510
|
<label class="sec-hint">${t('secretary.learn.goalRef')}</label>
|
|
376
511
|
<select class="sec-band" value=${f.goalRef} onChange=${(e) => p.setDecForm({ ...f, goalRef: e.target.value })}>
|
|
377
512
|
<option value="">—</option>
|
|
378
|
-
${p.goals.filter((g) => g.status !== 'done').map((g) => html`<option value=${'secretary.goal.' + g.id} selected=${f.goalRef === 'secretary.goal.' + g.id}>${
|
|
513
|
+
${p.goals.filter((g) => g.status !== 'done').map((g) => html`<option value=${'secretary.goal.' + g.id} selected=${f.goalRef === 'secretary.goal.' + g.id}>${(g.title)}</option>`)}
|
|
379
514
|
</select>
|
|
380
515
|
<label class="sec-hint">${t('secretary.learn.revisitIn')}</label>
|
|
381
516
|
<input class="sec-input sec-input-sm" type="number" min="0" value=${f.revisitDays} onInput=${(e) => p.setDecForm({ ...f, revisitDays: e.target.value })} />
|
|
@@ -387,10 +522,10 @@ export function decisionLogCard(p) {
|
|
|
387
522
|
: html`<ul class="sec-goal-list">
|
|
388
523
|
${p.decisions.map((d) => html`<li class="sec-goal-row" key=${d.id}>
|
|
389
524
|
<div class="sec-goal-main">
|
|
390
|
-
<div class="sec-goal-title">${
|
|
525
|
+
<div class="sec-goal-title">${(d.decision)}${d.chosen ? html` <span class="sec-hint">→ ${(d.chosen)}</span>` : null}</div>
|
|
391
526
|
${d.status === 'reviewed' && d.verdict
|
|
392
|
-
? html`<div class="sec-hint">${
|
|
393
|
-
: (d.expectedOutcome ? html`<div class="sec-hint">${t('secretary.learn.expected')}: ${
|
|
527
|
+
? html`<div class="sec-hint">${(d.verdict)}</div>`
|
|
528
|
+
: (d.expectedOutcome ? html`<div class="sec-hint">${t('secretary.learn.expected')}: ${(d.expectedOutcome)}</div>` : null)}
|
|
394
529
|
</div>
|
|
395
530
|
${scoreChip(d)}
|
|
396
531
|
<button class="btn-ghost btn-sm" onClick=${() => p.deleteDecision(d)}>✕</button>
|
|
@@ -409,11 +544,14 @@ export function metaCard(p) {
|
|
|
409
544
|
<section class="sec-card sec-meta-card">
|
|
410
545
|
<dl class="sec-meta">
|
|
411
546
|
<dt>${t('secretary.identity')}</dt>
|
|
412
|
-
<dd><code>${
|
|
547
|
+
<dd><code>${(p.secretary.gaii)}</code></dd>
|
|
413
548
|
<dt title=${t('secretary.reliabilityHint')}>${t('secretary.reliability')}</dt>
|
|
414
549
|
<dd>${relChip}</dd>
|
|
415
550
|
<dt>${t('secretary.scopes')}</dt>
|
|
416
|
-
<dd class="sec-scopes"
|
|
551
|
+
<dd class="sec-scopes">
|
|
552
|
+
${(p.secretary.default_scopes || []).map((s) => html`<span class="sec-scope" key=${s}>${s}</span>`)}
|
|
553
|
+
<a class="sec-perm-link" href="/v1/profile?tab=agents">${t('secretary.managePermissions')} ↗</a>
|
|
554
|
+
</dd>
|
|
417
555
|
</dl>
|
|
418
556
|
</section>`;
|
|
419
557
|
}
|