aimeat 1.33.2 → 1.34.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 +388 -14
- package/dist/locales/fi.json +388 -14
- 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 +412 -2
- 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 +262 -17
- package/dist/public/js/services/secretary-policy.js +1 -0
- 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 +7 -0
- package/dist/public/views/profile/agents/state-detector.js +6 -0
- package/dist/public/views/profile/agents/tab-integration.js +6 -0
- 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 +173 -66
- package/dist/public/views/secretary/dashboard.js +551 -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 +663 -39
- 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/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 +380 -5
- 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/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/offer-schemas.d.ts +8 -8
- 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 +29 -0
- package/dist/src/routes/secretary.d.ts.map +1 -0
- package/dist/src/routes/secretary.js +220 -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/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 +41 -2
- package/dist/src/services/scheduler.d.ts.map +1 -1
- package/dist/src/services/scheduler.js +429 -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/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
|
@@ -86,6 +86,7 @@ import { recordSecurityIncident } from '../services/security-incident.js';
|
|
|
86
86
|
import { updateWorkspaceMeta, WorkspaceMetaError } from '../services/workspace-meta.js';
|
|
87
87
|
import { countWorkspaceInstances, latestWorkspaceEvent, deriveWorkspaceEvents, aggregateParticipants } from '../services/workspace-enrichment.js';
|
|
88
88
|
import { buildOrganismOverview, buildWorkspaceOverview } from '../services/structure-overview.js';
|
|
89
|
+
import { archiveTarget, unarchiveTarget, isKeyArchived } from '../services/archive.js';
|
|
89
90
|
import { getOrganismReadme, setOrganismReadme } from '../services/organism-readme.js';
|
|
90
91
|
import { collectOrganismGraph, collectWorkspaceGraph } from '../services/structure-graph.js';
|
|
91
92
|
import { updateOrganismStructure } from '../services/structure-snapshot.js';
|
|
@@ -193,6 +194,10 @@ export function organismsRouter(config, storage) {
|
|
|
193
194
|
visibility: member ? (selfOrOperator ? visibility : 'public') : (visibility || 'public'),
|
|
194
195
|
page: page ? Number(page) : 1,
|
|
195
196
|
perPage: per_page ? Number(per_page) : 20,
|
|
197
|
+
// The owner's OWN list includes archived (the client splits them into an "Archived" section);
|
|
198
|
+
// browsing/discovery (anyone else, or no member filter) excludes archived — retired organisms
|
|
199
|
+
// are read-only and not discoverable.
|
|
200
|
+
archived: (member && selfOrOperator) ? 'include' : 'exclude',
|
|
196
201
|
});
|
|
197
202
|
// ?include=counts — attach workspace_count per org (distinct ids in the registry across all
|
|
198
203
|
// members' registry records), so the list view doesn't fan out one discoverWorkspaces per org.
|
|
@@ -997,12 +1002,33 @@ export function organismsRouter(config, storage) {
|
|
|
997
1002
|
// (No ws → legacy organism-level root, kept only so an un-scoped call still reads something.)
|
|
998
1003
|
const ws = typeof req.query.ws === 'string' ? req.query.ws : undefined;
|
|
999
1004
|
const nsRoot = ws ? `organism.${id}.w.${ws}.` : `organism.${id}.`;
|
|
1005
|
+
// Archived content is excluded by default (the AI working set); ?includeArchived=true surfaces it
|
|
1006
|
+
// — the explicit "look in archive" escape hatch. ?archived=only reads ONLY archived content.
|
|
1007
|
+
const archived = req.query.archived === 'only' ? 'only' : (req.query.includeArchived === 'true' ? 'include' : undefined);
|
|
1000
1008
|
// A workspace is SHARED: authorization is at the workspace level, not per record. If the caller can
|
|
1001
1009
|
// read the manifest (they created it, are a same-owner agent, or hold a viewer/contributor grant —
|
|
1002
1010
|
// see authorizeRead/the workspace-role consents), they see ALL of the workspace's content, whoever
|
|
1003
1011
|
// wrote it — so a contributor's writes are visible to the creator + other members. If not, they see
|
|
1004
1012
|
// nothing (org membership alone is discovery-only). The manifest is the single gate record.
|
|
1005
|
-
|
|
1013
|
+
// For the archived views we must still surface the (active) manifest/readme so the workspace can
|
|
1014
|
+
// render — otherwise `archived=only` would drop the manifest and the whole workspace reads empty.
|
|
1015
|
+
// So: include everything, then filter CONTENT by the requested view using each record's own flag
|
|
1016
|
+
// while always keeping the workspace's own meta.* (manifest/readme). Default (active) keeps the
|
|
1017
|
+
// efficient storage-level exclude.
|
|
1018
|
+
let items;
|
|
1019
|
+
if (archived === 'only' || archived === 'include') {
|
|
1020
|
+
const all = (await storage.listAllMemory({ prefix: nsRoot, limit: 5000, archived: 'include' })).items;
|
|
1021
|
+
// Keep ONLY the manifest + readme (so the workspace shell renders) plus the archived content.
|
|
1022
|
+
// NB: must match the manifest/readme EXACTLY, not a `meta.` prefix — an objectType namespace can
|
|
1023
|
+
// itself start with `meta.` (e.g. `meta.goals`), and a prefix filter would leak ACTIVE content
|
|
1024
|
+
// from those spaces into the archived-only view.
|
|
1025
|
+
items = archived === 'only'
|
|
1026
|
+
? all.filter(r => r.archived || r.key === `${nsRoot}meta.manifest` || r.key === `${nsRoot}meta.readme`)
|
|
1027
|
+
: all;
|
|
1028
|
+
}
|
|
1029
|
+
else {
|
|
1030
|
+
items = (await storage.listAllMemory({ prefix: nsRoot, limit: 5000 })).items;
|
|
1031
|
+
}
|
|
1006
1032
|
const manRec = items.find(r => r.key === `${nsRoot}meta.manifest`);
|
|
1007
1033
|
let canReadWorkspace = false;
|
|
1008
1034
|
if (manRec) {
|
|
@@ -1121,13 +1147,15 @@ export function organismsRouter(config, storage) {
|
|
|
1121
1147
|
return;
|
|
1122
1148
|
}
|
|
1123
1149
|
const viewerGaii = resolveIdentity(req.auth, config.nodeId);
|
|
1124
|
-
const
|
|
1150
|
+
const includeArchived = req.query.includeArchived === 'true';
|
|
1151
|
+
const { markdown, workspaces, archivedWorkspaces } = await buildOrganismOverview(storage, config, { orgId: id, viewerGaii, includeArchived });
|
|
1125
1152
|
if (req.query.format === 'md') {
|
|
1126
1153
|
res.type('text/markdown').send(markdown);
|
|
1127
1154
|
return;
|
|
1128
1155
|
}
|
|
1129
|
-
res.json(success(config.nodeId, { markdown, workspaces }, [
|
|
1156
|
+
res.json(success(config.nodeId, { markdown, workspaces, archivedWorkspaces }, [
|
|
1130
1157
|
{ description: 'Drill into one workspace', method: 'GET', url: `/v1/organisms/${id}/workspace/overview?ws=<ws>` },
|
|
1158
|
+
...(archivedWorkspaces && !includeArchived ? [{ description: 'Include archived workspaces', method: 'GET', url: `/v1/organisms/${id}/overview?includeArchived=true` }] : []),
|
|
1131
1159
|
]));
|
|
1132
1160
|
});
|
|
1133
1161
|
/* ── GET /v1/organisms/:id/workspace/overview — OKF-style overview of ONE workspace (Markdown) ──
|
|
@@ -1295,8 +1323,10 @@ export function organismsRouter(config, storage) {
|
|
|
1295
1323
|
return;
|
|
1296
1324
|
}
|
|
1297
1325
|
const callerGaii = resolveIdentity(req.auth, config.nodeId);
|
|
1298
|
-
|
|
1299
|
-
|
|
1326
|
+
// Default excludes archived; ?archived=only is "archive search"; ?includeArchived=true searches both.
|
|
1327
|
+
const archived = req.query.archived === 'only' ? 'only' : (req.query.includeArchived === 'true' ? 'include' : undefined);
|
|
1328
|
+
const { results, truncated } = await searchOrganismContent(storage, config, organism, callerGaii, q, onlyWs, { archived });
|
|
1329
|
+
res.json(success(config.nodeId, { query: q, results, total: results.length, truncated, archived: archived ?? 'exclude' }));
|
|
1300
1330
|
});
|
|
1301
1331
|
/* ── Comments / threads on workspace records + documents ──
|
|
1302
1332
|
* A comment targets one workspace object (record or document) by (ws, space, instance_id), can be
|
|
@@ -1725,7 +1755,8 @@ export function organismsRouter(config, storage) {
|
|
|
1725
1755
|
}
|
|
1726
1756
|
const callerGaii = resolveIdentity(req.auth, config.nodeId);
|
|
1727
1757
|
const ownerName = req.auth.owner;
|
|
1728
|
-
|
|
1758
|
+
// `include` so an archived organism's registry (cascade-archived with it) still lists workspaces.
|
|
1759
|
+
const { items } = await storage.listAllMemory({ prefix: wsRegPrefix(id), limit: 1000, archived: 'include' });
|
|
1729
1760
|
const seen = new Map();
|
|
1730
1761
|
for (const rec of items) {
|
|
1731
1762
|
if (rec.key !== wsRegPrefix(id))
|
|
@@ -1740,7 +1771,7 @@ export function organismsRouter(config, storage) {
|
|
|
1740
1771
|
access = 'owner';
|
|
1741
1772
|
else if (await canReadWs(id, w.id, callerGaii))
|
|
1742
1773
|
access = 'granted';
|
|
1743
|
-
seen.set(w.id, { id: w.id, name: w.name ?? w.id, created_by: createdBy, created_at: w.createdAt, access });
|
|
1774
|
+
seen.set(w.id, { id: w.id, name: w.name ?? w.id, created_by: createdBy, created_at: w.createdAt, access, archived: w.archived === true });
|
|
1744
1775
|
}
|
|
1745
1776
|
}
|
|
1746
1777
|
// ?include=enrichment — fold the per-workspace getWorkspace+activity+participants fan-out (3N
|
|
@@ -2291,6 +2322,12 @@ export function organismsRouter(config, storage) {
|
|
|
2291
2322
|
res.status(400).json(error(config.nodeId, 'INVALID_INPUT', 'ws is required'));
|
|
2292
2323
|
return;
|
|
2293
2324
|
}
|
|
2325
|
+
// Archived workspace/organism is read-only — block structure/name/readme edits.
|
|
2326
|
+
const wsGuard = await isKeyArchived(storage, `organism.${id}.w.${ws}.`);
|
|
2327
|
+
if (wsGuard.archived) {
|
|
2328
|
+
res.status(409).json(error(config.nodeId, 'ARCHIVED', `This ${wsGuard.level} is archived (read-only). Unarchive it before editing.`));
|
|
2329
|
+
return;
|
|
2330
|
+
}
|
|
2294
2331
|
try {
|
|
2295
2332
|
const result = await updateWorkspaceMeta(storage, config, {
|
|
2296
2333
|
orgId: id, ws, callerOwner: req.auth.owner,
|
|
@@ -2625,6 +2662,63 @@ export function organismsRouter(config, storage) {
|
|
|
2625
2662
|
if (ws)
|
|
2626
2663
|
void updateOrganismStructure(storage, config, id, { event: 'workspace deleted', actor: resolveIdentity(req.auth, config.nodeId) }).catch(() => { });
|
|
2627
2664
|
});
|
|
2665
|
+
/* ── Archive / Unarchive ──────────────────────────────────────────────────────────────────────
|
|
2666
|
+
* Flag an organism, a workspace, a record-table/document-space, or a single record as read-only +
|
|
2667
|
+
* archived so it drops out of every AI-facing material (overview, workspace read, search) yet stays
|
|
2668
|
+
* findable via archive search and resolvable by key. Cascades down a container with smart restore
|
|
2669
|
+
* (see services/archive.ts). Creator/admin only — archiving is a structural, destructive-adjacent op.
|
|
2670
|
+
* Body: { level: 'organism'|'workspace'|'space'|'record', ws?, namespace?, key? }. */
|
|
2671
|
+
const validateArchiveTarget = (id, body) => {
|
|
2672
|
+
const level = body.level;
|
|
2673
|
+
if (!['organism', 'workspace', 'space', 'record'].includes(level))
|
|
2674
|
+
return { ok: false, msg: 'level must be organism|workspace|space|record' };
|
|
2675
|
+
const ws = typeof body.ws === 'string' ? body.ws : undefined;
|
|
2676
|
+
const namespace = typeof body.namespace === 'string' ? body.namespace : undefined;
|
|
2677
|
+
const key = typeof body.key === 'string' ? body.key : undefined;
|
|
2678
|
+
if ((level === 'workspace' || level === 'space' || level === 'record') && !ws)
|
|
2679
|
+
return { ok: false, msg: 'ws is required for workspace/space/record' };
|
|
2680
|
+
if (level === 'space' && !namespace)
|
|
2681
|
+
return { ok: false, msg: 'namespace is required for space' };
|
|
2682
|
+
if (level === 'record') {
|
|
2683
|
+
if (!key)
|
|
2684
|
+
return { ok: false, msg: 'key is required for record' };
|
|
2685
|
+
if (!key.startsWith(`organism.${id}.w.${ws}.`))
|
|
2686
|
+
return { ok: false, msg: 'key must be inside organism.{id}.w.{ws}.' };
|
|
2687
|
+
}
|
|
2688
|
+
return { ok: true, target: { level, orgId: id, ws, namespace, key } };
|
|
2689
|
+
};
|
|
2690
|
+
const archiveHandler = (mode) => async (req, res) => {
|
|
2691
|
+
const id = req.params.id;
|
|
2692
|
+
const organism = await storage.getOrganism(id);
|
|
2693
|
+
if (!organism) {
|
|
2694
|
+
res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'Organism not found'));
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2697
|
+
const role = await memberRole(req, organism, id);
|
|
2698
|
+
if (role !== 'creator' && role !== 'admin') {
|
|
2699
|
+
res.status(403).json(error(config.nodeId, 'ACCESS_DENIED', `Only the creator or an admin can ${mode} organism content`));
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
const v = validateArchiveTarget(id, (req.body ?? {}));
|
|
2703
|
+
if (!v.ok) {
|
|
2704
|
+
res.status(400).json(error(config.nodeId, 'INVALID_INPUT', v.msg));
|
|
2705
|
+
return;
|
|
2706
|
+
}
|
|
2707
|
+
const actor = resolveIdentity(req.auth, config.nodeId);
|
|
2708
|
+
try {
|
|
2709
|
+
const result = mode === 'archive'
|
|
2710
|
+
? await archiveTarget(storage, v.target, actor)
|
|
2711
|
+
: await unarchiveTarget(storage, v.target, actor);
|
|
2712
|
+
res.json(success(config.nodeId, { [mode === 'archive' ? 'archived' : 'restored']: result.count, level: result.level, root: result.root }));
|
|
2713
|
+
emitChange('organisms');
|
|
2714
|
+
void updateOrganismStructure(storage, config, id, { event: `${v.target.level} ${mode}d`, actor }).catch(() => { });
|
|
2715
|
+
}
|
|
2716
|
+
catch (e) {
|
|
2717
|
+
res.status(400).json(error(config.nodeId, 'ARCHIVE_FAILED', e.message || `Could not ${mode}`));
|
|
2718
|
+
}
|
|
2719
|
+
};
|
|
2720
|
+
router.post('/v1/organisms/:id/archive', requireAuth(), requireRole('agent'), archiveHandler('archive'));
|
|
2721
|
+
router.post('/v1/organisms/:id/unarchive', requireAuth(), requireRole('agent'), archiveHandler('unarchive'));
|
|
2628
2722
|
// POST /v1/organisms/:id/approvals — request approval for an action (gate or auto-run).
|
|
2629
2723
|
router.post('/v1/organisms/:id/approvals', requireAuth(), async (req, res) => {
|
|
2630
2724
|
const id = req.params.id;
|
|
@@ -2713,6 +2807,12 @@ export function organismsRouter(config, storage) {
|
|
|
2713
2807
|
res.status(403).json(error(config.nodeId, 'ACCESS_DENIED', 'Admin/creator role required to publish in a meta.* namespace'));
|
|
2714
2808
|
return;
|
|
2715
2809
|
}
|
|
2810
|
+
// Archived content is read-only — block publishing into an archived organism/workspace.
|
|
2811
|
+
const pubGuard = await isKeyArchived(storage, wsId ? `organism.${id}.w.${wsId}.` : `organism.${id}.`);
|
|
2812
|
+
if (pubGuard.archived) {
|
|
2813
|
+
res.status(409).json(error(config.nodeId, 'ARCHIVED', `This ${pubGuard.level} is archived (read-only). Unarchive it before publishing.`));
|
|
2814
|
+
return;
|
|
2815
|
+
}
|
|
2716
2816
|
const publisher = resolveIdentity(req.auth, config.nodeId);
|
|
2717
2817
|
// Config decides whether publishing needs a review gate. Absent / disabled = publish now.
|
|
2718
2818
|
const cfg = await readConfig(id);
|