aimeat 1.34.0 → 1.36.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/.env.example +25 -0
- package/dist/locales/en.json +58 -6
- package/dist/locales/fi.json +58 -6
- package/dist/public/css/views/secretary.css +52 -0
- package/dist/public/js/i18n.js +9 -0
- package/dist/public/js/services/secretary-helpers.js +8 -4
- package/dist/public/js/services/secretary-policy.js +28 -3
- package/dist/public/spa.html +5 -1
- package/dist/public/views/my-company.js +13 -1
- package/dist/public/views/profile/agents/agent-card.js +6 -4
- package/dist/public/views/profile/agents/tab-integration.js +5 -2
- package/dist/public/views/secretary/cards.js +46 -15
- package/dist/public/views/secretary/dashboard.js +68 -2
- package/dist/public/views/secretary.js +221 -40
- package/dist/scripts/archive-stale-versions.d.ts +33 -0
- package/dist/scripts/archive-stale-versions.d.ts.map +1 -0
- package/dist/scripts/archive-stale-versions.js +278 -0
- package/dist/scripts/archive-stale-versions.js.map +1 -0
- package/dist/src/cli/connect/mcp/tools/agent-management.d.ts +4 -1
- package/dist/src/cli/connect/mcp/tools/agent-management.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/tools/agent-management.js +1 -1
- package/dist/src/cli/connect/mcp/tools/agent-management.js.map +1 -1
- 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/config.d.ts +11 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +12 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +748 -4
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/generated/prisma-postgres/edge.js +4 -3
- package/dist/src/generated/prisma-postgres/index-browser.js +1 -0
- package/dist/src/generated/prisma-postgres/index.d.ts +24 -1
- package/dist/src/generated/prisma-postgres/index.js +4 -3
- package/dist/src/generated/prisma-postgres/package.json +1 -1
- package/dist/src/generated/prisma-postgres/schema.prisma +1 -0
- package/dist/src/generated/prisma-postgres/wasm.js +4 -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/workspaces.d.ts +4 -0
- package/dist/src/mcp/workspaces.d.ts.map +1 -1
- package/dist/src/mcp/workspaces.js +16 -3
- 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/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/agents.d.ts +7 -0
- package/dist/src/routes/agents.d.ts.map +1 -1
- package/dist/src/routes/agents.js +48 -5
- package/dist/src/routes/agents.js.map +1 -1
- package/dist/src/routes/libs.d.ts +14 -0
- package/dist/src/routes/libs.d.ts.map +1 -1
- package/dist/src/routes/libs.js +56 -17
- package/dist/src/routes/libs.js.map +1 -1
- package/dist/src/routes/oauth-login.d.ts +26 -21
- package/dist/src/routes/oauth-login.d.ts.map +1 -1
- package/dist/src/routes/oauth-login.js +257 -229
- package/dist/src/routes/oauth-login.js.map +1 -1
- package/dist/src/routes/openrouter.d.ts +3 -0
- package/dist/src/routes/openrouter.d.ts.map +1 -1
- package/dist/src/routes/openrouter.js +10 -5
- package/dist/src/routes/openrouter.js.map +1 -1
- package/dist/src/routes/organisms.d.ts +4 -0
- package/dist/src/routes/organisms.d.ts.map +1 -1
- package/dist/src/routes/organisms.js +32 -5
- package/dist/src/routes/organisms.js.map +1 -1
- package/dist/src/routes/secretary.d.ts +7 -2
- package/dist/src/routes/secretary.d.ts.map +1 -1
- package/dist/src/routes/secretary.js +119 -28
- package/dist/src/routes/secretary.js.map +1 -1
- package/dist/src/routes/site.d.ts +2 -0
- package/dist/src/routes/site.d.ts.map +1 -1
- package/dist/src/routes/site.js +10 -2
- package/dist/src/routes/site.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +8 -15
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/services/ai-completion.d.ts +2 -0
- package/dist/src/services/ai-completion.d.ts.map +1 -1
- package/dist/src/services/ai-completion.js +2 -1
- package/dist/src/services/ai-completion.js.map +1 -1
- package/dist/src/services/config-schema.d.ts.map +1 -1
- package/dist/src/services/config-schema.js +2 -0
- package/dist/src/services/config-schema.js.map +1 -1
- package/dist/src/services/generator-autopilot.d.ts +2 -0
- package/dist/src/services/generator-autopilot.d.ts.map +1 -1
- package/dist/src/services/generator-autopilot.js +3 -1
- package/dist/src/services/generator-autopilot.js.map +1 -1
- package/dist/src/services/notebook-ai.d.ts +2 -0
- package/dist/src/services/notebook-ai.d.ts.map +1 -1
- package/dist/src/services/notebook-ai.js +1 -1
- package/dist/src/services/notebook-ai.js.map +1 -1
- package/dist/src/services/oidc-providers.d.ts +94 -0
- package/dist/src/services/oidc-providers.d.ts.map +1 -0
- package/dist/src/services/oidc-providers.js +181 -0
- package/dist/src/services/oidc-providers.js.map +1 -0
- 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-template.d.ts.map +1 -1
- package/dist/src/services/organism-template.js +3 -1
- package/dist/src/services/organism-template.js.map +1 -1
- package/dist/src/services/scheduler.d.ts +9 -0
- package/dist/src/services/scheduler.d.ts.map +1 -1
- package/dist/src/services/scheduler.js +53 -24
- package/dist/src/services/scheduler.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 +5 -0
- package/dist/src/services/skill-bundle/generator.d.ts.map +1 -1
- package/dist/src/services/skill-bundle/generator.js +22 -1
- package/dist/src/services/skill-bundle/generator.js.map +1 -1
- package/dist/src/storage/interface.d.ts +2 -1
- 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 +1 -0
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +27 -0
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +1 -0
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +18 -4
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +6 -0
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/identity.repository.d.ts +2 -0
- package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -1
- package/dist/src/utils/env-config.d.ts.map +1 -1
- package/dist/src/utils/env-config.js +11 -0
- package/dist/src/utils/env-config.js.map +1 -1
- package/dist/src/utils/node-descriptor.d.ts.map +1 -1
- package/dist/src/utils/node-descriptor.js +1 -0
- package/dist/src/utils/node-descriptor.js.map +1 -1
- package/package.json +3 -1
- package/prisma/schema.postgres.prisma +1 -0
- package/prisma/schema.prisma +1 -0
package/dist/.env.example
CHANGED
|
@@ -269,6 +269,31 @@ AIMEAT_PORT=40050
|
|
|
269
269
|
# AIMEAT_GOOGLE_OAUTH_CLIENT_SECRET="" # OAuth 2.0 client secret
|
|
270
270
|
# AIMEAT_GOOGLE_OAUTH_REDIRECT_URI="" # default: <baseUrl>/v1/ghii/login/google/callback
|
|
271
271
|
|
|
272
|
+
# ── Social login — Casdoor sign-in (OIDC) ────────────────────
|
|
273
|
+
# Casdoor is an open-source IdP. In its admin: create an Application, add the redirect URI below,
|
|
274
|
+
# then copy the client id/secret here. Casdoor is the authority for its org's accounts, so AIMEAT
|
|
275
|
+
# treats emails it returns as verified (enables link-by-email) — only enable IdPs you trust for that.
|
|
276
|
+
# AIMEAT_CASDOOR_OAUTH_ENABLED=false
|
|
277
|
+
# AIMEAT_CASDOOR_OAUTH_ENDPOINT="" # Casdoor server URL, e.g. https://casdoor.example.com
|
|
278
|
+
# AIMEAT_CASDOOR_OAUTH_CLIENT_ID="" # Application client ID from Casdoor
|
|
279
|
+
# AIMEAT_CASDOOR_OAUTH_CLIENT_SECRET="" # Application client secret from Casdoor
|
|
280
|
+
# AIMEAT_CASDOOR_OAUTH_REDIRECT_URI="" # default: <baseUrl>/v1/ghii/login/casdoor/callback
|
|
281
|
+
|
|
282
|
+
# ── Social login — Microsoft Entra ID sign-in (OIDC) ─────────
|
|
283
|
+
# Register an app (free) at https://entra.microsoft.com → App registrations. Add a "Web" platform
|
|
284
|
+
# with the redirect URI below and create a client secret. TENANT controls who may sign in:
|
|
285
|
+
# • a Directory (tenant) GUID → ONLY that org's members (enterprise gating; AIMEAT also checks the
|
|
286
|
+
# `tid` claim and treats the email as verified so members auto-link).
|
|
287
|
+
# • common → any work/school account AND personal Microsoft accounts (widest).
|
|
288
|
+
# • organizations → any work/school account (any org). • consumers → personal accounts only.
|
|
289
|
+
# Note: for the non-GUID modes strict issuer validation can be finicky; pin a tenant GUID for the
|
|
290
|
+
# most reliable + gated setup.
|
|
291
|
+
# AIMEAT_ENTRA_OAUTH_ENABLED=false
|
|
292
|
+
# AIMEAT_ENTRA_OAUTH_TENANT="common" # tenant GUID | common | organizations | consumers
|
|
293
|
+
# AIMEAT_ENTRA_OAUTH_CLIENT_ID="" # Application (client) ID from the app registration
|
|
294
|
+
# AIMEAT_ENTRA_OAUTH_CLIENT_SECRET="" # Client secret value from the app registration
|
|
295
|
+
# AIMEAT_ENTRA_OAUTH_REDIRECT_URI="" # default: <baseUrl>/v1/ghii/login/entra/callback
|
|
296
|
+
|
|
272
297
|
# ── Consul (optional fleet management) ───────────────────────
|
|
273
298
|
# Connect to HashiCorp Consul for centralized config management across nodes.
|
|
274
299
|
# Values in Consul KV take precedence over file/.env but below database overrides.
|
package/dist/locales/en.json
CHANGED
|
@@ -559,7 +559,7 @@
|
|
|
559
559
|
"wf": {
|
|
560
560
|
"title": "Design a workflow",
|
|
561
561
|
"quick": "Design workflow",
|
|
562
|
-
"prompt": "Describe the outcome you want — I'll chain your specialists
|
|
562
|
+
"prompt": "Describe the outcome you want — I'll chain your specialists and Builders into a workflow (a multi-step pipeline) to reach it.",
|
|
563
563
|
"placeholder": "e.g. Every evening, gather the day's news and publish an edition…",
|
|
564
564
|
"design": "Design",
|
|
565
565
|
"designing": "Designing the chain…",
|
|
@@ -742,10 +742,28 @@
|
|
|
742
742
|
"apply": "Set up my Secretary",
|
|
743
743
|
"applying": "Setting up…",
|
|
744
744
|
"hireDone": "Your Secretary is set up.",
|
|
745
|
+
"briefsReady": "Work briefs ready to hand to a Builder",
|
|
745
746
|
"fillingWorkspaces": "Filling your workspaces with real content…",
|
|
746
747
|
"workspacesFilled": "Workspaces filled with real content",
|
|
748
|
+
"workspacesFilledIssues": "couldn't fill these yet",
|
|
747
749
|
"emptyRemoved": "empty ones removed",
|
|
748
750
|
"fillError": "Couldn't fill the workspaces",
|
|
751
|
+
"settingUpTitle": "Setting up your Secretary…",
|
|
752
|
+
"settingUpHint": "Hang tight — this can take a minute while it writes real content into each workspace.",
|
|
753
|
+
"stepStructure": "Creating your space and workspaces…",
|
|
754
|
+
"stepFilling": "Filling workspace",
|
|
755
|
+
"stepDone": "Done — finishing up…",
|
|
756
|
+
"mode": {
|
|
757
|
+
"title": "How should your Secretary work?",
|
|
758
|
+
"intro": "Either way, it fills your workspaces with real content right now. This choice is about what it does ON ITS OWN afterwards. You can change it any time.",
|
|
759
|
+
"draftTitle": "Prepare things for me (recommended)",
|
|
760
|
+
"draftDesc": "It keeps your workspaces up to date on its own and drafts what's next — but leaves it for you to approve. Nothing is published without your OK. Uses your AI credits.",
|
|
761
|
+
"actTitle": "Run things for me",
|
|
762
|
+
"actDesc": "Fully autonomous: it fills, updates and publishes on its own, every day, without asking. Uses your AI credits.",
|
|
763
|
+
"offTitle": "Only when I ask",
|
|
764
|
+
"offDesc": "It fills your workspaces now, then waits. It won't spend or act on its own until you turn it on.",
|
|
765
|
+
"changeLater": "You can change this any time under the Secretary's “How I work”."
|
|
766
|
+
},
|
|
749
767
|
"hireError": "Couldn't set up the Secretary",
|
|
750
768
|
"hireBadShape": "The pasted result is missing required fields (brain.purpose, organism.name, workspaces).",
|
|
751
769
|
"hiredStatus": "Secretary is set up",
|
|
@@ -760,6 +778,13 @@
|
|
|
760
778
|
"inappError": "Couldn't generate",
|
|
761
779
|
"inappEmpty": "The AI returned nothing.",
|
|
762
780
|
"howIWork": "How I work",
|
|
781
|
+
"autonomy": {
|
|
782
|
+
"suggest": "Suggest only",
|
|
783
|
+
"suggestHint": "I watch, keep things current, and surface what needs attention — but I ask before acting.",
|
|
784
|
+
"assist": "Handle the small stuff",
|
|
785
|
+
"assistHint": "I also file notes, post reminders and briefings on my own. Heavy work is always a Work Brief you hand to a Builder."
|
|
786
|
+
},
|
|
787
|
+
"advancedBands": "Advanced — per-capability control",
|
|
763
788
|
"stopSpending": "Stop spending",
|
|
764
789
|
"stopSpendingHint": "Pause everything that costs morsels or acts on its own. The Secretary can still think, draft, and message you.",
|
|
765
790
|
"dailyBudget": "Daily morsel budget",
|
|
@@ -981,6 +1006,24 @@
|
|
|
981
1006
|
"reliability": "Reliability",
|
|
982
1007
|
"reliabilityBuilding": "building…",
|
|
983
1008
|
"reliabilityHint": "Average score of the Secretary's reviewed decisions — its own track record, not its marketplace trust.",
|
|
1009
|
+
"brief": {
|
|
1010
|
+
"startHere": "👉 Start here:",
|
|
1011
|
+
"title": "Hand to a Builder",
|
|
1012
|
+
"subtitle": "Heavy work the Secretary prepared — a big AI builds it via MCP. You never invent content here.",
|
|
1013
|
+
"mcpNote": "Open one in Claude Desktop (it needs your AIMEAT MCP connected), or send it to an already-connected Builder.",
|
|
1014
|
+
"connectLink": "Connect a Builder",
|
|
1015
|
+
"heavyBadge": "Heavy",
|
|
1016
|
+
"dispatchedBadge": "Dispatched",
|
|
1017
|
+
"preview": "Preview what the Builder receives",
|
|
1018
|
+
"openClaude": "Open in Claude Desktop",
|
|
1019
|
+
"sendBuilder": "Send to a connected Builder…",
|
|
1020
|
+
"waiting": "Waiting on the Builder…",
|
|
1021
|
+
"dispatchedNote": "Sent — the Builder is working on it via MCP. This clears itself when the task finishes (or use Done).",
|
|
1022
|
+
"noBuilder": "Connect a Builder to dispatch",
|
|
1023
|
+
"done": "Done",
|
|
1024
|
+
"dispatched": "Brief sent to the Builder.",
|
|
1025
|
+
"dispatchFailed": "Couldn't dispatch the brief."
|
|
1026
|
+
},
|
|
984
1027
|
"dash": {
|
|
985
1028
|
"todayTitle": "Today",
|
|
986
1029
|
"refresh": "Refresh",
|
|
@@ -1039,7 +1082,7 @@
|
|
|
1039
1082
|
"startNewTitle": "Start something new",
|
|
1040
1083
|
"nextStep": "Next step",
|
|
1041
1084
|
"allSettled": "all steps settled",
|
|
1042
|
-
"hint": "Tell me a goal — I'll propose a repeatable routine
|
|
1085
|
+
"hint": "Tell me a goal — I'll propose a repeatable routine: light, recurring checks I run and track myself (for heavy building, I hand a Builder a Work Brief instead). Approve each step (band-gated).",
|
|
1043
1086
|
"placeholder": "What do you want to make progress on?",
|
|
1044
1087
|
"propose": "Propose a routine",
|
|
1045
1088
|
"proposing": "Designing…",
|
|
@@ -1072,7 +1115,9 @@
|
|
|
1072
1115
|
"delegateWorkflowPick": "Run a workflow…",
|
|
1073
1116
|
"delegateWorkflowGo": "Run workflow",
|
|
1074
1117
|
"delegateDesignWf": "Design new workflow",
|
|
1075
|
-
"delegatePick": "Pick
|
|
1118
|
+
"delegatePick": "Pick who runs it…",
|
|
1119
|
+
"delegateSpecialists": "Specialists (node-local)",
|
|
1120
|
+
"delegateBuilders": "Builders (connected AI)",
|
|
1076
1121
|
"delegateGo": "Delegate",
|
|
1077
1122
|
"delegateNoAgent": "Pick an agent to delegate to first",
|
|
1078
1123
|
"delegateNoAgents": "No other agents to delegate to — connect one in Manage → crew.",
|
|
@@ -4902,6 +4947,8 @@
|
|
|
4902
4947
|
"cancelBtn": "Cancel",
|
|
4903
4948
|
"orLabel": "OR",
|
|
4904
4949
|
"googleSignIn": "Continue with Google",
|
|
4950
|
+
"casdoorSignIn": "Continue with Casdoor",
|
|
4951
|
+
"entraSignIn": "Continue with Microsoft",
|
|
4905
4952
|
"working": "Working...",
|
|
4906
4953
|
"errUserShort": "Username must be at least 3 characters",
|
|
4907
4954
|
"errPassShort": "Password must be at least 4 characters",
|
|
@@ -4934,11 +4981,13 @@
|
|
|
4934
4981
|
"sendUsername": "Send My Username",
|
|
4935
4982
|
"usernameSent": "If an account with that email exists, your username was sent.",
|
|
4936
4983
|
"signupTitle": "Choose your username",
|
|
4937
|
-
"signupIntro": "You're signing in
|
|
4984
|
+
"signupIntro": "You're signing in for the first time. Pick the username for your AIMEAT account.",
|
|
4938
4985
|
"signupEmailNote": "Signing up as {email}",
|
|
4939
4986
|
"signupUsernameLabel": "Username",
|
|
4940
|
-
"signupSuggestedHint": "We suggested one from your
|
|
4987
|
+
"signupSuggestedHint": "We suggested one from your account — change it to anything you like.",
|
|
4941
4988
|
"signupPermanentWarning": "⚠️ This username is permanent. It identifies you across AIMEAT and cannot be changed later — the only way to change it is to delete your account and create a new one.",
|
|
4989
|
+
"signupDisplayNameLabel": "Display name",
|
|
4990
|
+
"signupDisplayNameHint": "Shown to others — not permanent, you can change it anytime later.",
|
|
4942
4991
|
"signupAvailable": "✓ Available",
|
|
4943
4992
|
"signupTaken": "That username is already taken — pick another.",
|
|
4944
4993
|
"signupInvalid": "Username must be 3–64 characters: lowercase letters, numbers and hyphens.",
|
|
@@ -8108,7 +8157,10 @@
|
|
|
8108
8157
|
"complete_test_task": "Complete Test Task",
|
|
8109
8158
|
"publish_commands": "Publish Slash Commands",
|
|
8110
8159
|
"publish_config": "Publish Runtime Config",
|
|
8111
|
-
"declare_services": "Declare Services"
|
|
8160
|
+
"declare_services": "Declare Services",
|
|
8161
|
+
"declare_offerings": "Declare Offerings",
|
|
8162
|
+
"make_workflow_compatible": "Make an Offer Workflow-Compatible",
|
|
8163
|
+
"price_offer": "Price an Offer"
|
|
8112
8164
|
},
|
|
8113
8165
|
"stepDescriptions": {
|
|
8114
8166
|
"authenticate": "Agent is authenticated via device auth",
|
package/dist/locales/fi.json
CHANGED
|
@@ -559,7 +559,7 @@
|
|
|
559
559
|
"wf": {
|
|
560
560
|
"title": "Suunnittele workflow",
|
|
561
561
|
"quick": "Suunnittele workflow",
|
|
562
|
-
"prompt": "Kuvaa haluttu lopputulema — ketjutan specialistisi
|
|
562
|
+
"prompt": "Kuvaa haluttu lopputulema — ketjutan specialistisi ja Builderit workflow:ksi (monivaiheinen putki) sen saavuttamiseksi.",
|
|
563
563
|
"placeholder": "esim. Joka ilta kokoa päivän uutiset ja julkaise painos…",
|
|
564
564
|
"design": "Suunnittele",
|
|
565
565
|
"designing": "Suunnittelen ketjua…",
|
|
@@ -742,10 +742,28 @@
|
|
|
742
742
|
"apply": "Pystytä sihteerini",
|
|
743
743
|
"applying": "Pystytetään…",
|
|
744
744
|
"hireDone": "Sihteerisi on pystytetty.",
|
|
745
|
+
"briefsReady": "Työbriiffit valmiina annettavaksi Builderille",
|
|
745
746
|
"fillingWorkspaces": "Täytetään työtilojasi oikealla sisällöllä…",
|
|
746
747
|
"workspacesFilled": "Työtilat täytetty oikealla sisällöllä",
|
|
748
|
+
"workspacesFilledIssues": "näitä ei voitu vielä täyttää",
|
|
747
749
|
"emptyRemoved": "tyhjiä poistettu",
|
|
748
750
|
"fillError": "Työtilojen täyttö epäonnistui",
|
|
751
|
+
"settingUpTitle": "Pystytetään sihteeriäsi…",
|
|
752
|
+
"settingUpHint": "Hetki — tämä voi kestää minuutin, kun se kirjoittaa oikeaa sisältöä jokaiseen työtilaan.",
|
|
753
|
+
"stepStructure": "Luodaan tila ja työtilat…",
|
|
754
|
+
"stepFilling": "Täytetään työtila",
|
|
755
|
+
"stepDone": "Valmis — viimeistellään…",
|
|
756
|
+
"mode": {
|
|
757
|
+
"title": "Miten sihteerisi toimii?",
|
|
758
|
+
"intro": "Kummassakin tapauksessa se täyttää työtilasi oikealla sisällöllä heti nyt. Tämä valinta koskee sitä mitä se tekee OMIN PÄIN sen jälkeen. Voit muuttaa tätä milloin vain.",
|
|
759
|
+
"draftTitle": "Valmistele puolestani (suositus)",
|
|
760
|
+
"draftDesc": "Pitää työtilat ajan tasalla itse ja luonnostelee seuraavat askeleet — mutta jättää ne sinun hyväksyttäväksesi. Mitään ei julkaista ilman lupaasi. Käyttää AI-krediittejäsi.",
|
|
761
|
+
"actTitle": "Hoida puolestani",
|
|
762
|
+
"actDesc": "Täysin autonominen: täyttää, päivittää ja julkaisee itse, joka päivä, kysymättä. Käyttää AI-krediittejäsi.",
|
|
763
|
+
"offTitle": "Vain kun pyydän",
|
|
764
|
+
"offDesc": "Täyttää työtilat nyt, sitten odottaa. Ei kuluta eikä toimi omin päin ennen kuin laitat sen päälle.",
|
|
765
|
+
"changeLater": "Voit muuttaa tätä milloin vain sihteerin ”How I work” -kohdasta."
|
|
766
|
+
},
|
|
749
767
|
"hireError": "Sihteerin pystytys epäonnistui",
|
|
750
768
|
"hireBadShape": "Liitetystä tuloksesta puuttuu pakollisia kenttiä (brain.purpose, organism.name, workspaces).",
|
|
751
769
|
"hiredStatus": "Sihteeri on pystytetty",
|
|
@@ -760,6 +778,13 @@
|
|
|
760
778
|
"inappError": "Luonti epäonnistui",
|
|
761
779
|
"inappEmpty": "AI ei palauttanut mitään.",
|
|
762
780
|
"howIWork": "Miten toimin",
|
|
781
|
+
"autonomy": {
|
|
782
|
+
"suggest": "Vain ehdota",
|
|
783
|
+
"suggestHint": "Seuraan, pidän asiat ajan tasalla ja nostan esiin mikä vaatii huomiota — mutta kysyn ennen kuin toimin.",
|
|
784
|
+
"assist": "Hoida pienet asiat",
|
|
785
|
+
"assistHint": "Kirjaan myös muistiinpanot, muistutukset ja briiffit itse. Raskas työ on aina Work Brief jonka annat Builderille."
|
|
786
|
+
},
|
|
787
|
+
"advancedBands": "Lisäasetukset — kyvykkyyskohtainen hallinta",
|
|
763
788
|
"stopSpending": "Lopeta kulutus",
|
|
764
789
|
"stopSpendingHint": "Keskeytä kaikki mikä kuluttaa morsseja tai toimii itsenäisesti. Sihteeri voi yhä ajatella, luonnostella ja viestiä sinulle.",
|
|
765
790
|
"dailyBudget": "Päivittäinen morssi-budjetti",
|
|
@@ -981,6 +1006,24 @@
|
|
|
981
1006
|
"reliability": "Luotettavuus",
|
|
982
1007
|
"reliabilityBuilding": "kerätään…",
|
|
983
1008
|
"reliabilityHint": "Sihteerin arvioitujen päätösten keskiarvopistemäärä — sen oma näyttö, ei markkinapaikan luottamus.",
|
|
1009
|
+
"brief": {
|
|
1010
|
+
"startHere": "👉 Aloita tästä:",
|
|
1011
|
+
"title": "Anna Builderille",
|
|
1012
|
+
"subtitle": "Raskas työ jonka Sihteeri valmisteli — iso äly rakentaa sen MCP:llä. Et keksi sisältöä täällä.",
|
|
1013
|
+
"mcpNote": "Avaa yksi Claude Desktopissa (siinä pitää olla AIMEAT-MCP kytkettynä), tai lähetä jo kytketylle Builderille.",
|
|
1014
|
+
"connectLink": "Kytke Builder",
|
|
1015
|
+
"heavyBadge": "Raskas",
|
|
1016
|
+
"dispatchedBadge": "Lähetetty",
|
|
1017
|
+
"preview": "Esikatsele mitä Builder saa",
|
|
1018
|
+
"openClaude": "Avaa Claude Desktopissa",
|
|
1019
|
+
"sendBuilder": "Lähetä kytketylle Builderille…",
|
|
1020
|
+
"waiting": "Odotetaan Builderia…",
|
|
1021
|
+
"dispatchedNote": "Lähetetty — Builder työstää sitä MCP:llä. Tämä poistuu itsestään kun task valmistuu (tai paina Valmis).",
|
|
1022
|
+
"noBuilder": "Kytke Builder lähettääksesi",
|
|
1023
|
+
"done": "Valmis",
|
|
1024
|
+
"dispatched": "Briiffi lähetetty Builderille.",
|
|
1025
|
+
"dispatchFailed": "Briiffin lähetys epäonnistui."
|
|
1026
|
+
},
|
|
984
1027
|
"dash": {
|
|
985
1028
|
"todayTitle": "Tänään",
|
|
986
1029
|
"refresh": "Päivitä",
|
|
@@ -1039,7 +1082,7 @@
|
|
|
1039
1082
|
"startNewTitle": "Aloita jotain uutta",
|
|
1040
1083
|
"nextStep": "Seuraava vaihe",
|
|
1041
1084
|
"allSettled": "kaikki vaiheet käsitelty",
|
|
1042
|
-
"hint": "Kerro tavoite — ehdotan toistettavan rutiinin. Hyväksy jokainen vaihe (lupakaistan mukaan)
|
|
1085
|
+
"hint": "Kerro tavoite — ehdotan toistettavan rutiinin: kevyitä, toistuvia tarkistuksia jotka ajan ja seuraan itse (raskaaseen rakentamiseen annan Builderille Work Briefin). Hyväksy jokainen vaihe (lupakaistan mukaan).",
|
|
1043
1086
|
"placeholder": "Missä haluat edistyä?",
|
|
1044
1087
|
"propose": "Ehdota rutiinia",
|
|
1045
1088
|
"proposing": "Suunnitellaan…",
|
|
@@ -1072,7 +1115,9 @@
|
|
|
1072
1115
|
"delegateWorkflowPick": "Aja työnkulku…",
|
|
1073
1116
|
"delegateWorkflowGo": "Aja työnkulku",
|
|
1074
1117
|
"delegateDesignWf": "Suunnittele uusi workflow",
|
|
1075
|
-
"delegatePick": "Valitse
|
|
1118
|
+
"delegatePick": "Valitse kuka ajaa sen…",
|
|
1119
|
+
"delegateSpecialists": "Specialistit (node-paikalliset)",
|
|
1120
|
+
"delegateBuilders": "Builderit (kytketty AI)",
|
|
1076
1121
|
"delegateGo": "Delegoi",
|
|
1077
1122
|
"delegateNoAgent": "Valitse ensin agentti, jolle delegoidaan",
|
|
1078
1123
|
"delegateNoAgents": "Ei muita agentteja delegoitavaksi — yhdistä sellainen kohdassa Hallinta → tiimi.",
|
|
@@ -4902,6 +4947,8 @@
|
|
|
4902
4947
|
"cancelBtn": "Peruuta",
|
|
4903
4948
|
"orLabel": "TAI",
|
|
4904
4949
|
"googleSignIn": "Jatka Googlella",
|
|
4950
|
+
"casdoorSignIn": "Jatka Casdoorilla",
|
|
4951
|
+
"entraSignIn": "Jatka Microsoftilla",
|
|
4905
4952
|
"working": "Käsitellään...",
|
|
4906
4953
|
"errUserShort": "Käyttäjänimen tulee olla vähintään 3 merkkiä",
|
|
4907
4954
|
"errPassShort": "Salasanan tulee olla vähintään 4 merkkiä",
|
|
@@ -4934,11 +4981,13 @@
|
|
|
4934
4981
|
"sendUsername": "Lähetä käyttäjätunnukseni",
|
|
4935
4982
|
"usernameSent": "Jos sähköpostiosoitteella on tili, käyttäjätunnus lähetettiin.",
|
|
4936
4983
|
"signupTitle": "Valitse käyttäjätunnuksesi",
|
|
4937
|
-
"signupIntro": "Kirjaudut
|
|
4984
|
+
"signupIntro": "Kirjaudut ensimmäistä kertaa. Valitse AIMEAT-tilisi käyttäjätunnus.",
|
|
4938
4985
|
"signupEmailNote": "Rekisteröidyt osoitteella {email}",
|
|
4939
4986
|
"signupUsernameLabel": "Käyttäjätunnus",
|
|
4940
|
-
"signupSuggestedHint": "Ehdotimme tunnusta
|
|
4987
|
+
"signupSuggestedHint": "Ehdotimme tunnusta tilisi perusteella — voit vaihtaa sen mihin tahansa.",
|
|
4941
4988
|
"signupPermanentWarning": "⚠️ Tämä käyttäjätunnus on pysyvä. Se tunnistaa sinut koko AIMEATissa eikä sitä voi vaihtaa jälkikäteen — ainoa tapa muuttaa se on poistaa tili ja luoda uusi.",
|
|
4989
|
+
"signupDisplayNameLabel": "Näyttönimi",
|
|
4990
|
+
"signupDisplayNameHint": "Näkyy muille — ei pysyvä, voit vaihtaa sen milloin tahansa myöhemmin.",
|
|
4942
4991
|
"signupAvailable": "✓ Vapaa",
|
|
4943
4992
|
"signupTaken": "Tämä käyttäjätunnus on jo varattu — valitse toinen.",
|
|
4944
4993
|
"signupInvalid": "Käyttäjätunnuksen pituus 3–64 merkkiä: pieniä kirjaimia, numeroita ja väliviivoja.",
|
|
@@ -8108,7 +8157,10 @@
|
|
|
8108
8157
|
"complete_test_task": "Suorita testitehtävä",
|
|
8109
8158
|
"publish_commands": "Julkaise slash-komennot",
|
|
8110
8159
|
"publish_config": "Julkaise runtime-konfiguraatio",
|
|
8111
|
-
"declare_services": "Ilmoita palvelut"
|
|
8160
|
+
"declare_services": "Ilmoita palvelut",
|
|
8161
|
+
"declare_offerings": "Ilmoita tarjoukset",
|
|
8162
|
+
"make_workflow_compatible": "Tee tarjouksesta työnkulkuyhteensopiva",
|
|
8163
|
+
"price_offer": "Hinnoittele tarjous"
|
|
8112
8164
|
},
|
|
8113
8165
|
"stepDescriptions": {
|
|
8114
8166
|
"authenticate": "Agentti on tunnistautunut laitevarmennuksen kautta",
|
|
@@ -1016,3 +1016,55 @@
|
|
|
1016
1016
|
display: flex; flex-direction: column; gap: 0.5rem;
|
|
1017
1017
|
}
|
|
1018
1018
|
.sec-modal .sec-input, .sec-modal .sec-stand-body { margin-top: 0.2rem; }
|
|
1019
|
+
|
|
1020
|
+
/* Live setup-progress overlay — a top-level modal shown through the whole setup (incl. the slow fill),
|
|
1021
|
+
surviving the hire→dashboard switch so the owner always sees what's happening and how far along it is. */
|
|
1022
|
+
.sec-setup-overlay { position: fixed; inset: 0; z-index: 3000; display: flex; align-items: center; justify-content: center;
|
|
1023
|
+
background: rgba(0, 0, 0, 0.45); padding: 1rem; }
|
|
1024
|
+
.sec-setup-box { background: var(--card); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow);
|
|
1025
|
+
padding: 1.25rem 1.5rem; width: min(28rem, 96vw); display: flex; flex-direction: column; gap: 0.5rem; }
|
|
1026
|
+
.sec-setup-row { display: flex; align-items: center; gap: 0.5rem; font-weight: 600; margin: 0.25rem 0 0.5rem; }
|
|
1027
|
+
.sec-progress-bar { height: 8px; border-radius: 999px; background: var(--bg-dim, var(--border)); overflow: hidden; }
|
|
1028
|
+
.sec-progress-fill { height: 100%; background: var(--accent); border-radius: 999px; transition: width 0.4s ease; }
|
|
1029
|
+
|
|
1030
|
+
/* "How should your Secretary work?" autonomy step (asked once, up front, during setup). */
|
|
1031
|
+
.sec-mode-box { width: min(34rem, 96vw); }
|
|
1032
|
+
.sec-mode-opt { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.6rem 0.75rem; border: 1px solid var(--border);
|
|
1033
|
+
border-radius: 10px; cursor: pointer; }
|
|
1034
|
+
.sec-mode-opt + .sec-mode-opt { margin-top: 0.4rem; }
|
|
1035
|
+
.sec-mode-opt--on { border-color: var(--accent); background: var(--bg-dim, var(--card)); }
|
|
1036
|
+
.sec-mode-opt input { margin-top: 0.2rem; accent-color: var(--accent); }
|
|
1037
|
+
.sec-mode-opt-t { font-weight: 700; display: block; }
|
|
1038
|
+
|
|
1039
|
+
/* Work Brief tray — heavy work the Secretary prepared for a Builder (the light-vs-heavy seam). */
|
|
1040
|
+
.sec-brief-tray { border-color: var(--accent-border, var(--accent)); }
|
|
1041
|
+
.sec-brief-tray .sec-count { font-size: 0.78rem; font-weight: 600; padding: 0.05rem 0.45rem; border-radius: 999px;
|
|
1042
|
+
background: var(--accent-soft, var(--bg-dim)); color: var(--accent); margin-left: 0.35rem; }
|
|
1043
|
+
.sec-brief-banner { margin: 0 0 0.5rem; padding: 0.45rem 0.6rem; font-size: 0.82rem; color: var(--text-dim);
|
|
1044
|
+
background: var(--bg-dim); border: 1px solid var(--border); border-radius: var(--radius-sm, 8px); }
|
|
1045
|
+
.sec-brief-wait { margin-top: 0.3rem; }
|
|
1046
|
+
.sec-brief { padding: 0.65rem 0; border-top: 1px solid var(--border); }
|
|
1047
|
+
.sec-brief:first-of-type { border-top: none; }
|
|
1048
|
+
.sec-brief-top { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.45rem; }
|
|
1049
|
+
.sec-brief-obj { font-weight: 600; color: var(--text); }
|
|
1050
|
+
.sec-brief-ws { margin-left: auto; }
|
|
1051
|
+
.sec-brief-badge { font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
|
|
1052
|
+
padding: 0.05rem 0.4rem; border-radius: 999px; background: var(--accent-soft, var(--bg-dim));
|
|
1053
|
+
border: 1px solid var(--accent-border, var(--accent)); color: var(--accent); }
|
|
1054
|
+
.sec-brief-badge.is-dispatched { background: var(--info-bg, var(--bg-dim)); border-color: var(--info-border, var(--border)); color: var(--info-fg, var(--text-dim)); }
|
|
1055
|
+
.sec-brief-detail { margin: 0.4rem 0; }
|
|
1056
|
+
.sec-brief-detail > summary { cursor: pointer; color: var(--accent); font-size: 0.82rem; }
|
|
1057
|
+
.sec-brief-md { margin-top: 0.5rem; padding: 0.6rem 0.75rem; background: var(--bg-dim); border: 1px solid var(--border);
|
|
1058
|
+
border-radius: var(--radius-sm, 8px); max-height: 22rem; overflow: auto; font-size: 0.85rem; }
|
|
1059
|
+
.sec-brief-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.35rem; }
|
|
1060
|
+
.sec-select { padding: 0.3rem 0.5rem; border: 1px solid var(--border); border-radius: var(--radius-sm, 8px);
|
|
1061
|
+
background: var(--card); color: var(--text); font-size: 0.82rem; }
|
|
1062
|
+
|
|
1063
|
+
/* One autonomy toggle (collapses the per-capability band sprawl). */
|
|
1064
|
+
.sec-autonomy { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.75rem; }
|
|
1065
|
+
.sec-auto-opt { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.55rem 0.7rem; border: 1px solid var(--border);
|
|
1066
|
+
border-radius: 10px; cursor: pointer; }
|
|
1067
|
+
.sec-auto-opt--on { border-color: var(--accent); background: var(--bg-dim, var(--card)); }
|
|
1068
|
+
.sec-auto-opt input { margin-top: 0.2rem; accent-color: var(--accent); }
|
|
1069
|
+
.sec-adv { margin-top: 0.75rem; }
|
|
1070
|
+
.sec-adv > summary { cursor: pointer; color: var(--text-dim); font-size: 0.85rem; }
|
package/dist/public/js/i18n.js
CHANGED
|
@@ -63,6 +63,15 @@ export function t(key, vars) {
|
|
|
63
63
|
return str;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
/** Translate a key, but fall back to `fallbackText` when the key is missing.
|
|
67
|
+
* t() returns the raw key string on a miss (truthy), which defeats the common
|
|
68
|
+
* `t(key) || serverProvidedTitle` pattern -- use this when a server-provided
|
|
69
|
+
* label should win over a raw key. */
|
|
70
|
+
export function tOr(key, fallbackText, vars) {
|
|
71
|
+
const val = t(key, vars);
|
|
72
|
+
return val === key ? (fallbackText ?? key) : val;
|
|
73
|
+
}
|
|
74
|
+
|
|
66
75
|
/** Get current locale. */
|
|
67
76
|
export function getLocale() {
|
|
68
77
|
return currentLocale;
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* @structure CONTRACT · buildInterviewPrompt · buildDesignPrompt · extractJson · snapshotOf · genCtxId · sanitizeQuickActions · migrateConfig · buildDecisionRecord
|
|
9
9
|
* @usage import { buildInterviewPrompt, extractJson, sanitizeQuickActions, migrateConfig } from '/js/services/secretary-helpers.js';
|
|
10
10
|
* @version-history
|
|
11
|
+
* v0.7.0 — 2026-06-30 — Sharpen the CONTRACT to state the rule plainly: DOCUMENTS ARE THE DEFAULT (most
|
|
12
|
+
* workspaces are flexible information → mostly/all document spaces); a RECORDS space is only for
|
|
13
|
+
* same-shaped, list-like data (actions/tasks/bugs/pipeline/tracker) and legitimately starts empty —
|
|
14
|
+
* so the user's AI stops over-producing rigid record spaces that the don't-invent fill leaves blank.
|
|
11
15
|
* v0.6.0 — 2026-06-30 — CONTRACT steers the design toward DOCUMENT spaces (free-form markdown, the
|
|
12
16
|
* default) and treats RECORDS spaces as the exception (only genuine lists/task-sets) — workspaces
|
|
13
17
|
* were coming out mostly as rigid record spaces.
|
|
@@ -85,10 +89,10 @@ export const CONTRACT = `\`\`\`json
|
|
|
85
89
|
}
|
|
86
90
|
\`\`\`
|
|
87
91
|
|
|
88
|
-
A workspace's "manifest.objectTypes" are its SPACES, and each space is one of two kinds.
|
|
89
|
-
- A DOCUMENT space — free-form markdown pages about a topic (guides, write-ups, notes, plans, analysis, anything). Declare it as { "name": "<type>", "namespace": "<ns>", "mode": "document" } with NO fields and NO schema. This is the DEFAULT
|
|
90
|
-
- A RECORDS space — a schema-locked list where every entry shares the SAME fixed fields. Use this ONLY
|
|
91
|
-
|
|
92
|
+
A workspace's "manifest.objectTypes" are its SPACES, and each space is one of two kinds. DOCUMENTS ARE THE DEFAULT — most workspaces are flexible information and should be all (or mostly) document spaces:
|
|
93
|
+
- A DOCUMENT space — free-form markdown pages about a topic (guides, write-ups, notes, plans, analysis, anything). Declare it as { "name": "<type>", "namespace": "<ns>", "mode": "document" } with NO fields and NO schema. This is the DEFAULT: it holds any kind of information and can be shaped and edited freely. When in doubt, use a document space.
|
|
94
|
+
- A RECORDS space — a schema-locked list where every entry shares the SAME fixed fields. Use this ONLY for genuinely list-like, repeating data: actions, tasks, bugs, a sales pipeline, a tracker — the SAME shape over and over, that you add rows to over time. Declare it as { "name": "<type>", "namespace": "<ns>", "mode": "records", "fields": [ { "name": "<field>", "type": "text|number|date|select|boolean|reference" } ] } AND provide a matching JSON Schema under "schemas" keyed by its namespace. A records space legitimately starts empty and fills as real items occur — so do not use one for content you want written up now.
|
|
95
|
+
Default to document spaces; reach for a records space only when same-shaped, list-like rows clearly fit. A workspace may be entirely document spaces. Full manifest shape: { "manifestVersion": "1.0", "name": "<the workspace name>", "kind": "<short-slug>", "status": "active", "objectTypes": [ …the spaces above ] }.
|
|
92
96
|
If you are NOT confident you can produce a VALID manifest + schemas, OMIT both fields for that workspace — they will be designed automatically afterward. Never output an invalid or half-finished manifest.
|
|
93
97
|
|
|
94
98
|
"strategy" is the OPTIONAL steering frame for this area: where we are, where we're going, and how. Include it ONLY when the user wants this area steered that way (many goal-driven areas benefit; some areas are just ongoing upkeep — then OMIT the field entirely). EVERY sub-field is itself optional — include only the ones the user gave you real material for; never invent vision/mission/progress/names. When included:
|
|
@@ -7,9 +7,14 @@
|
|
|
7
7
|
* autonomous tick read it); for now it is authored + persisted here. Bands: act (do it + log) /
|
|
8
8
|
* draft (prepare, ask to approve) / ask (decision card) / off. `discover` is locked to act + free
|
|
9
9
|
* (read-only, never blocked by stop-spending). Full design: docs/plans/2026-06-23-secretary-feature.md §6/§9.
|
|
10
|
-
* @structure BANDS · SECRETARY_CAPABILITIES · defaultPolicy() · mergePolicy()
|
|
11
|
-
* @usage import { SECRETARY_CAPABILITIES, BANDS, defaultPolicy } from '/js/services/secretary-policy.js';
|
|
10
|
+
* @structure BANDS · SECRETARY_CAPABILITIES · LIGHT_AUTONOMY_CAPS · defaultPolicy() · mergePolicy() · autonomyPreset() · autonomyLevelOf()
|
|
11
|
+
* @usage import { SECRETARY_CAPABILITIES, BANDS, defaultPolicy, autonomyPreset, autonomyLevelOf } from '/js/services/secretary-policy.js';
|
|
12
12
|
* @version-history
|
|
13
|
+
* v0.3.0 — 2026-07-01 — Light-vs-heavy seam: dropped `author_content` (heavy authoring is now a Work
|
|
14
|
+
* Brief a Builder executes, never a band). Added the two-state autonomy preset (autonomyPreset /
|
|
15
|
+
* autonomyLevelOf + LIGHT_AUTONOMY_CAPS) so the UI can show ONE toggle (suggest-only vs handle-the-
|
|
16
|
+
* small-stuff) that sets the underlying per-capability bands — the band machinery + parity tests are
|
|
17
|
+
* unchanged; the toggle is sugar over the same bands map.
|
|
13
18
|
* v0.2.0 — 2026-06-24 — Phase 3d: mark Enterprise-only capabilities (third-party messaging, transacting,
|
|
14
19
|
* spending) with `enterprise: true` — gated/locked in the Community Secretary (which lacks the
|
|
15
20
|
* messages:send / work:request / wallet scopes). The explicit third-party-send gate.
|
|
@@ -31,7 +36,6 @@ export const SECRETARY_CAPABILITIES = [
|
|
|
31
36
|
{ id: 'file_intake', defaultBand: 'act' },
|
|
32
37
|
{ id: 'briefing', defaultBand: 'act' },
|
|
33
38
|
{ id: 'reminders', defaultBand: 'act' },
|
|
34
|
-
{ id: 'author_content', defaultBand: 'off', costs: true },
|
|
35
39
|
{ id: 'curate_knowledge', defaultBand: 'draft' },
|
|
36
40
|
{ id: 'draft_replies', defaultBand: 'draft' },
|
|
37
41
|
{ id: 'create_resource', defaultBand: 'ask' },
|
|
@@ -41,6 +45,10 @@ export const SECRETARY_CAPABILITIES = [
|
|
|
41
45
|
{ id: 'spend', defaultBand: 'ask', costs: true, enterprise: true },
|
|
42
46
|
];
|
|
43
47
|
|
|
48
|
+
/** The LIGHT capabilities the one autonomy toggle flips: in "assist" they act, in "suggest" they only
|
|
49
|
+
* surface (ask). Everything else keeps its conservative default — heavy work is never a band, it's a Brief. */
|
|
50
|
+
export const LIGHT_AUTONOMY_CAPS = ['file_intake', 'briefing', 'reminders', 'curate_knowledge'];
|
|
51
|
+
|
|
44
52
|
/** The conservative default operating model seeded when the Secretary is hired. */
|
|
45
53
|
export function defaultPolicy() {
|
|
46
54
|
const bands = {};
|
|
@@ -48,6 +56,23 @@ export function defaultPolicy() {
|
|
|
48
56
|
return { stopSpending: false, dailyMorselBudget: null, bands };
|
|
49
57
|
}
|
|
50
58
|
|
|
59
|
+
/** The two-state autonomy preset behind the single UI toggle. 'suggest' = the Secretary only surfaces
|
|
60
|
+
* things for you (light caps → ask); 'assist' = it handles the small stuff itself (light caps → act).
|
|
61
|
+
* Returns a full bands map (the other capabilities keep their conservative defaults). */
|
|
62
|
+
export function autonomyPreset(level) {
|
|
63
|
+
const bands = {};
|
|
64
|
+
for (const c of SECRETARY_CAPABILITIES) bands[c.id] = c.defaultBand;
|
|
65
|
+
const lightBand = level === 'assist' ? 'act' : 'ask';
|
|
66
|
+
for (const id of LIGHT_AUTONOMY_CAPS) if (bands[id] !== undefined) bands[id] = lightBand;
|
|
67
|
+
return bands;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Which preset a stored bands map looks like: 'assist' iff every light cap is acting, else 'suggest'. */
|
|
71
|
+
export function autonomyLevelOf(bands) {
|
|
72
|
+
const b = bands || {};
|
|
73
|
+
return LIGHT_AUTONOMY_CAPS.every((id) => b[id] === 'act') ? 'assist' : 'suggest';
|
|
74
|
+
}
|
|
75
|
+
|
|
51
76
|
/** Merge a stored (possibly partial / older) policy onto the current defaults so new capabilities
|
|
52
77
|
* always have a band and locked ones stay correct. */
|
|
53
78
|
export function mergePolicy(stored) {
|
package/dist/public/spa.html
CHANGED
|
@@ -544,6 +544,9 @@
|
|
|
544
544
|
const [morsels, setMorsels] = useState(null);
|
|
545
545
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
546
546
|
const [secretaryAvailable, setSecretaryAvailable] = useState(false);
|
|
547
|
+
// Node feature flags from /v1/site/header-nav (e.g. { secretary }). Empty until the fetch resolves,
|
|
548
|
+
// so optional surfaces stay hidden until we positively learn they're enabled (no flash).
|
|
549
|
+
const [features, setFeatures] = useState({});
|
|
547
550
|
// Header nav config: { order, hidden }. Defaults to all visible in declared order
|
|
548
551
|
// until the public /v1/site/header-nav fetch resolves (no flash of empty nav).
|
|
549
552
|
const [navConfig, setNavConfig] = useState({ order: PUBLIC_NAV_LINKS.map(l => l.id), hidden: [] });
|
|
@@ -574,6 +577,7 @@
|
|
|
574
577
|
const order = Array.isArray(d.data.order) ? d.data.order : PUBLIC_NAV_LINKS.map(l => l.id);
|
|
575
578
|
const hidden = Array.isArray(d.data.hidden) ? d.data.hidden : [];
|
|
576
579
|
setNavConfig({ order, hidden });
|
|
580
|
+
setFeatures(d.data.features || {});
|
|
577
581
|
})
|
|
578
582
|
.catch(e => console.warn('Header nav fetch failed:', e.message));
|
|
579
583
|
return () => { cancelled = true; };
|
|
@@ -644,7 +648,7 @@
|
|
|
644
648
|
class="${link.matchActive !== false && currentPath === link.path ? 'active' : ''}">${t(link.key) || link.fallback || link.key}</a>
|
|
645
649
|
`)}
|
|
646
650
|
${session && html`
|
|
647
|
-
${secretaryAvailable && html`
|
|
651
|
+
${secretaryAvailable && features.secretary && html`
|
|
648
652
|
<a href="/v1/secretary" class="sec-nav-link ${currentPath === '/v1/secretary' ? 'active' : ''}"
|
|
649
653
|
title=${t('nav.secretary')} onClick=${(e) => { handleNav(e, '/v1/secretary'); setMenuOpen(false); }}>
|
|
650
654
|
<span class="sec-nav-icon"><svg viewBox="0 0 24 24" aria-hidden="true">
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
* (revenue / orders / cost-per-task / commission income + per-agent table) from GET /v1/orgs/:slug/governance.
|
|
23
23
|
* v0.7.0 — 2026-06-24 — Secretary Phase 6 (slice 1): Company model admin subtab — prompt-driven builder
|
|
24
24
|
* (describe → generate in-app / copy-prompt → review → apply) for departments/roles/people/reporting (GET/PUT /v1/orgs/:slug/model).
|
|
25
|
+
* v0.8.0 — 2026-07-01 — Company Secretary subtab hidden unless the node enables the Secretary feature
|
|
26
|
+
* (AIMEAT_SECRETARY_ENABLED, read from /v1/site/header-nav `features.secretary`). Governance + model unaffected.
|
|
25
27
|
*/
|
|
26
28
|
import { h } from 'preact';
|
|
27
29
|
import { useState, useEffect, useCallback } from 'preact/hooks';
|
|
@@ -760,6 +762,7 @@ export default function MyCompanyView() {
|
|
|
760
762
|
const [newName, setNewName] = useState('');
|
|
761
763
|
const [newBusinessId, setNewBusinessId] = useState('');
|
|
762
764
|
const [busy, setBusy] = useState(false);
|
|
765
|
+
const [featSecretary, setFeatSecretary] = useState(false); // node opt-in: show the company Secretary subtab
|
|
763
766
|
|
|
764
767
|
async function loadOrgs() {
|
|
765
768
|
setState('loading');
|
|
@@ -771,6 +774,15 @@ export default function MyCompanyView() {
|
|
|
771
774
|
}
|
|
772
775
|
}
|
|
773
776
|
useEffect(() => { loadOrgs(); }, []);
|
|
777
|
+
// Company Secretary is opt-in per node (AIMEAT_SECRETARY_ENABLED); hide its admin subtab when off.
|
|
778
|
+
useEffect(() => {
|
|
779
|
+
let cancelled = false;
|
|
780
|
+
fetch('/v1/site/header-nav')
|
|
781
|
+
.then(r => r.json())
|
|
782
|
+
.then(d => { if (!cancelled && d?.ok) setFeatSecretary(!!(d.data?.features && d.data.features.secretary)); })
|
|
783
|
+
.catch(() => {});
|
|
784
|
+
return () => { cancelled = true; };
|
|
785
|
+
}, []);
|
|
774
786
|
|
|
775
787
|
async function loadOrders(org) {
|
|
776
788
|
try { const r = await apiGet(`/v1/orgs/${encodeURIComponent(org.slug)}/orders`); setOrdersReceived(r.data?.orders ?? []); }
|
|
@@ -872,7 +884,7 @@ export default function MyCompanyView() {
|
|
|
872
884
|
</div>
|
|
873
885
|
|
|
874
886
|
<div class="mc-subtabs">
|
|
875
|
-
${['catalog', ...(selected.role === 'admin' ? ['orders', 'customers', 'portfolio', 'secretary', 'governance', 'model', 'settings'] : []), 'members'].map(id => html`
|
|
887
|
+
${['catalog', ...(selected.role === 'admin' ? ['orders', 'customers', 'portfolio', ...(featSecretary ? ['secretary'] : []), 'governance', 'model', 'settings'] : []), 'members'].map(id => html`
|
|
876
888
|
<button class="mc-subtab ${subTab === id ? 'active' : ''}" key=${id} onClick=${() => setSubTab(id)}>${t('myCompany.tab' + id.charAt(0).toUpperCase() + id.slice(1))}</button>`)}
|
|
877
889
|
<span class="mc-role-chip">${t('myCompany.role' + (selected.role || 'member').charAt(0).toUpperCase() + (selected.role || 'member').slice(1))}</span>
|
|
878
890
|
</div>
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* @description Agent card component with collapsed/expanded states,
|
|
4
4
|
* Two-Zone Header (identity + state-dependent status), and tab bar.
|
|
5
5
|
* @version-history
|
|
6
|
+
* v1.18.0 -- 2026-06-30 -- Onboarding step labels use tOr() so a missing agentOnboarding.steps.*
|
|
7
|
+
* key falls back to the server-provided step.title instead of rendering the raw key.
|
|
6
8
|
* v1.17.0 -- 2026-06-24 -- Secretary P5 (S-A): render a "Specialist · <role>" badge for agents tagged
|
|
7
9
|
* system:specialist, so the new specialist agent type is recognizable in the Agents tab.
|
|
8
10
|
* v1.16.0 -- 2026-06-21 -- Unseen-change badges are now has-unseen DOTS (no count) — the
|
|
@@ -59,7 +61,7 @@
|
|
|
59
61
|
import { h } from 'preact';
|
|
60
62
|
import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
|
|
61
63
|
import htm from 'htm';
|
|
62
|
-
import { t } from '/js/i18n.js';
|
|
64
|
+
import { t, tOr } from '/js/i18n.js';
|
|
63
65
|
import { apiGet, apiPatch } from '/js/api.js';
|
|
64
66
|
import { timeAgo } from '/js/utils.js';
|
|
65
67
|
import { detectAgentState, getDefaultTab, getStateColor } from './state-detector.js';
|
|
@@ -437,7 +439,7 @@ function renderCollapsedStats(state, agent, onboarding) {
|
|
|
437
439
|
return html`${agent.last_seen ? `${t('profile.agents.detail.lastSeen')}: ${timeAgo(agent.last_seen)}` : ''} | ${t('profile.agents.detail.state.newSummary')}`;
|
|
438
440
|
case 'onboarding': {
|
|
439
441
|
const nextStep = onboarding?.steps?.find(s => s.status === 'pending');
|
|
440
|
-
return html`${agent.last_seen ? `${t('profile.agents.detail.lastSeen')}: ${timeAgo(agent.last_seen)}` : ''} ${nextStep ? `| ${t('profile.agents.detail.state.next')}: ${
|
|
442
|
+
return html`${agent.last_seen ? `${t('profile.agents.detail.lastSeen')}: ${timeAgo(agent.last_seen)}` : ''} ${nextStep ? `| ${t('profile.agents.detail.state.next')}: ${tOr('agentOnboarding.steps.' + nextStep.id, nextStep.title || nextStep.id)}` : ''}`;
|
|
441
443
|
}
|
|
442
444
|
case 'problem':
|
|
443
445
|
return html`${t('profile.agents.detail.state.problemSummary')} | ${agent.last_seen ? `${t('profile.agents.detail.lastSeen')}: ${timeAgo(agent.last_seen)}` : ''}`;
|
|
@@ -483,7 +485,7 @@ function renderZone2(state, agent, onboarding, setActiveTab, showToast) {
|
|
|
483
485
|
<div class="pf-agd-zone2 pf-agd-zone2--onboarding">
|
|
484
486
|
<div class="pf-agd-zone2-title">
|
|
485
487
|
${t('profile.agents.detail.zone2.onboardingTitle')}: ${passed} / ${total}
|
|
486
|
-
${nextStep ? html`<span class="pf-agd-zone2-desc"> ${t('profile.agents.detail.state.next')}: ${
|
|
488
|
+
${nextStep ? html`<span class="pf-agd-zone2-desc"> ${t('profile.agents.detail.state.next')}: ${tOr('agentOnboarding.steps.' + nextStep.id, nextStep.title || nextStep.id)}</span>` : ''}
|
|
487
489
|
</div>
|
|
488
490
|
<div class="pf-agd-progress-bar">
|
|
489
491
|
<div class="pf-agd-progress-fill" style="width: ${pct}%"></div>
|
|
@@ -491,7 +493,7 @@ function renderZone2(state, agent, onboarding, setActiveTab, showToast) {
|
|
|
491
493
|
<div class="pf-agd-step-pills">
|
|
492
494
|
${steps.map(s => html`
|
|
493
495
|
<span key=${s.id} class="pf-agd-step-pill pf-agd-step-pill--${s.status}">
|
|
494
|
-
${s.status === 'passed' ? '✓' : '○'} ${
|
|
496
|
+
${s.status === 'passed' ? '✓' : '○'} ${tOr('agentOnboarding.steps.' + s.id, s.title || s.id)}
|
|
495
497
|
</span>
|
|
496
498
|
`)}
|
|
497
499
|
</div>
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* during onboarding or production status (connection, platform, readiness,
|
|
5
5
|
* identity, delivery log) after completion.
|
|
6
6
|
* @version-history
|
|
7
|
+
* v1.8.0 -- 2026-06-30 -- Onboarding checklist step labels use tOr() so a missing
|
|
8
|
+
* agentOnboarding.steps.* key falls back to the server-provided step.title (which carries
|
|
9
|
+
* the howTo-enriched onboarding payload) instead of rendering the raw i18n key.
|
|
7
10
|
* v1.7.0 -- 2026-06-10 -- Webhook fields (URL, fail count, Test/Edit) hidden while delivery
|
|
8
11
|
* is polling; a "+ Set up webhook" reveal opens the URL form for switching methods.
|
|
9
12
|
* v1.6.0 -- 2026-06-02 -- Component unification (#1): the 3 copy buttons (agent prompt,
|
|
@@ -29,7 +32,7 @@ import { h } from 'preact';
|
|
|
29
32
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
30
33
|
import htm from 'htm';
|
|
31
34
|
import { onLiveUpdate } from '/lib/live-updates.js';
|
|
32
|
-
import { t } from '/js/i18n.js';
|
|
35
|
+
import { t, tOr } from '/js/i18n.js';
|
|
33
36
|
import { timeAgo } from '/js/utils.js';
|
|
34
37
|
import { CopyButton } from '/components/CopyButton.js';
|
|
35
38
|
import { detectAgentState } from './state-detector.js';
|
|
@@ -241,7 +244,7 @@ function renderOnboardingView(onboarding, agentName, handleRerun, rerunning, cur
|
|
|
241
244
|
<span class="pf-agd-step-icon">
|
|
242
245
|
${step.status === 'passed' ? '✓' : step.status === 'failed' ? '✗' : '○'}
|
|
243
246
|
</span>
|
|
244
|
-
<span class="pf-agd-step-name">${i + 1}. ${
|
|
247
|
+
<span class="pf-agd-step-name">${i + 1}. ${tOr('agentOnboarding.steps.' + step.id, step.title || step.id)}</span>
|
|
245
248
|
<span class="pf-agd-step-detail">
|
|
246
249
|
${step.validatedAt ? timeAgo(step.validatedAt) : ''}
|
|
247
250
|
${step.validationDetail ? ` -- ${step.validationDetail}` : ''}
|