aimeat 1.23.0 → 1.23.2
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 +138 -104
- package/dist/locales/fi.json +164 -130
- package/dist/public/css/theme.css +25 -10
- package/dist/public/css/views/profile.css +67 -3
- package/dist/public/js/services/organisms.js +28 -5
- package/dist/public/views/profile/organisms-tab.js +1057 -473
- package/dist/src/cli/connect/mcp/tools/organisms.d.ts +3 -0
- package/dist/src/cli/connect/mcp/tools/organisms.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/tools/organisms.js +20 -3
- package/dist/src/cli/connect/mcp/tools/organisms.js.map +1 -1
- package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
- package/dist/src/cli/connect/tool-call.js +20 -1
- package/dist/src/cli/connect/tool-call.js.map +1 -1
- package/dist/src/mcp/core.d.ts +4 -0
- package/dist/src/mcp/core.d.ts.map +1 -1
- package/dist/src/mcp/core.js +24 -0
- package/dist/src/mcp/core.js.map +1 -1
- package/dist/src/mcp/organisms.d.ts +3 -0
- package/dist/src/mcp/organisms.d.ts.map +1 -1
- package/dist/src/mcp/organisms.js +18 -0
- package/dist/src/mcp/organisms.js.map +1 -1
- package/dist/src/routes/organisms.d.ts.map +1 -1
- package/dist/src/routes/organisms.js +27 -5
- package/dist/src/routes/organisms.js.map +1 -1
- package/dist/src/services/schema-validator.d.ts.map +1 -1
- package/dist/src/services/schema-validator.js +12 -0
- package/dist/src/services/schema-validator.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
@usage Loaded first in spa.html <head>; the theme is toggled by /js/theme.js
|
|
11
11
|
which flips the data-theme attribute on <html>.
|
|
12
12
|
@version-history
|
|
13
|
+
v1.19.0 — 2026-06-10 — Controls get their own surface: new --control-bg/--control-border tokens
|
|
14
|
+
(light: white + gray-300; dark: raised #262934 + #4A4E5A). .btn-outline/.btn-ghost drop
|
|
15
|
+
background:transparent (they melted into the page as "framed text") and .input-field drops
|
|
16
|
+
background:var(--bg) (fields were LITERALLY the page color) — all three now use the control
|
|
17
|
+
tokens, buttons additionally get --shadow-sm so they read as pressable.
|
|
13
18
|
v1.18.0 — 2026-06-02 — Component unification (#10 third toast pathway): tokenize the shared .toast color literals. Added a theme-invariant --toast-success-bg (green-500 #22C55E @ .95, the legacy toast green — deliberately NOT --success emerald, which would shift the hue), --toast-danger-bg (= --danger #EF4444 @ .95) and --toast-fg (white), same rationale as the badge palette. The base .toast and the .toast.error/.toast-error/.toast-success modifiers now reference these tokens instead of raw rgba()/#fff. Appearance-preserving: identical resolved values; solid saturated pills intentionally do not flip in dark mode. profile.js keeps its own showToast pathway (distinct .pf.toast-container wrapper + .toast.error markup) — left as a convergence candidate, NOT migrated, to avoid changing DOM/behavior.
|
|
14
19
|
v1.17.0 — 2026-06-02 — Component unification (#26 recipient badge): add a theme-invariant --badge-*-bg palette (wildcard→danger, ghii→purple, organism→success, gaii→blue; domain #F97316 / node #6B7280 kept as own invariant swatches as they have no palette match) + --badge-fg white, so the profile .badge-* recipient classifier can drop its hardcoded hex (#8b5cf6/#f97316/#6b7280/#3b82f6) and dead light-only fallbacks (var(--success,#22c55e)/var(--danger,#ef4444)). Appearance-preserving: values resolve identically and these solid swatches intentionally do not flip in dark mode.
|
|
15
20
|
v1.16.0 — 2026-06-02 — Component unification (#25 pill base): add a canonical token-only .pill shape primitive (inline-flex chip, --radius-full, compact padding, small bold text, pointer + opacity hover) — shape only, no colors; tints come from caller classes. Mirrors the shape the profile .vis-pill already used. The scoped .pf .vis-pill keeps its own shape declaration (the (0,2,0)-beats-bare-.pill specificity trap) but its radius was retokenized to the same --radius-full so the two stay in lockstep.
|
|
@@ -140,6 +145,12 @@
|
|
|
140
145
|
--bg-input: var(--bg);
|
|
141
146
|
--bg-input-focus: #FFFFFF;
|
|
142
147
|
|
|
148
|
+
/* Controls (outline/ghost buttons, input fields) — a surface DISTINCT from both the page bg and
|
|
149
|
+
white cards: white fill + a clearly visible border, so controls read as controls instead of
|
|
150
|
+
"framed text" that melts into the background. */
|
|
151
|
+
--control-bg: #FFFFFF;
|
|
152
|
+
--control-border: #D1D5DB;
|
|
153
|
+
|
|
143
154
|
/* Code */
|
|
144
155
|
--code-bg: #F3F4F6;
|
|
145
156
|
|
|
@@ -238,6 +249,10 @@
|
|
|
238
249
|
--bg-input: #1C1E26;
|
|
239
250
|
--bg-input-focus: #23262F;
|
|
240
251
|
|
|
252
|
+
/* Controls — slightly lighter than the card surface so they read as raised, with a visible border */
|
|
253
|
+
--control-bg: #262934;
|
|
254
|
+
--control-border: #4A4E5A;
|
|
255
|
+
|
|
241
256
|
/* Code */
|
|
242
257
|
--code-bg: #0E0F13;
|
|
243
258
|
|
|
@@ -603,8 +618,8 @@ a { color: inherit; text-decoration: none; }
|
|
|
603
618
|
|
|
604
619
|
.btn-outline {
|
|
605
620
|
padding: 0.65rem 1.5rem;
|
|
606
|
-
background:
|
|
607
|
-
border: 1px solid var(--border);
|
|
621
|
+
background: var(--control-bg);
|
|
622
|
+
border: 1px solid var(--control-border);
|
|
608
623
|
border-radius: var(--radius-sm);
|
|
609
624
|
color: var(--text-dim);
|
|
610
625
|
font-size: 0.84rem;
|
|
@@ -613,15 +628,15 @@ a { color: inherit; text-decoration: none; }
|
|
|
613
628
|
cursor: pointer;
|
|
614
629
|
transition: all 0.15s;
|
|
615
630
|
letter-spacing: 0;
|
|
616
|
-
box-shadow:
|
|
631
|
+
box-shadow: var(--shadow-sm);
|
|
617
632
|
animation: none;
|
|
618
633
|
}
|
|
619
634
|
|
|
620
635
|
.btn-outline:hover {
|
|
621
636
|
border-color: var(--text-muted);
|
|
622
637
|
color: var(--text);
|
|
623
|
-
background:
|
|
624
|
-
box-shadow:
|
|
638
|
+
background: var(--control-bg);
|
|
639
|
+
box-shadow: var(--shadow-sm);
|
|
625
640
|
transform: none;
|
|
626
641
|
}
|
|
627
642
|
|
|
@@ -680,8 +695,8 @@ a { color: inherit; text-decoration: none; }
|
|
|
680
695
|
gap: 0.35rem;
|
|
681
696
|
padding: 7px 16px;
|
|
682
697
|
border-radius: var(--radius-sm);
|
|
683
|
-
border: 1px solid var(--border);
|
|
684
|
-
background:
|
|
698
|
+
border: 1px solid var(--control-border);
|
|
699
|
+
background: var(--control-bg);
|
|
685
700
|
color: var(--text-dim);
|
|
686
701
|
text-decoration: none;
|
|
687
702
|
font-size: 0.81rem;
|
|
@@ -692,7 +707,7 @@ a { color: inherit; text-decoration: none; }
|
|
|
692
707
|
.btn-ghost:hover {
|
|
693
708
|
border-color: var(--text-muted);
|
|
694
709
|
color: var(--text);
|
|
695
|
-
background:
|
|
710
|
+
background: var(--control-bg);
|
|
696
711
|
}
|
|
697
712
|
|
|
698
713
|
/* ── Cards ── */
|
|
@@ -1040,8 +1055,8 @@ a { color: inherit; text-decoration: none; }
|
|
|
1040
1055
|
.input-field {
|
|
1041
1056
|
width: 100%;
|
|
1042
1057
|
padding: 11px 14px;
|
|
1043
|
-
background: var(--bg);
|
|
1044
|
-
border: 1.5px solid var(--border);
|
|
1058
|
+
background: var(--control-bg);
|
|
1059
|
+
border: 1.5px solid var(--control-border);
|
|
1045
1060
|
border-radius: var(--radius-sm);
|
|
1046
1061
|
color: var(--text);
|
|
1047
1062
|
font-family: var(--font);
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* wallet, memory, agents, extensions, packages, knowledge, generator, and
|
|
5
5
|
* edit panels. Consumes theme.css tokens so it flips with dark/light mode.
|
|
6
6
|
* @version-history
|
|
7
|
+
* v1.14.0 — 2026-06-10 — SchemaForm usability: .pj-field-hint (per-field hint),
|
|
8
|
+
* .pj-field-invalid (missing-required outline) + .pj-form-error message.
|
|
9
|
+
* v1.13.0 — 2026-06-10 — Workspace renew, phase 2: .pj-ws-head-actions, review
|
|
10
|
+
* .pj-ws-banner, .pj-ws-tab-add (+ reuses .pj-org-tabs underline tabs).
|
|
7
11
|
* v1.12.0 — 2026-06-10 — Organisms list renew, phase 1: compact .pj-org-row list
|
|
8
12
|
* (avatar, one-line meta, kebab menu, drag-over state), .pj-menu dropdown,
|
|
9
13
|
* organism home page (.pj-org-home-head, underline .pj-org-tabs, breadcrumb).
|
|
@@ -2035,9 +2039,6 @@
|
|
|
2035
2039
|
|
|
2036
2040
|
/* Workspace breadcrumb — keeps the parent organism visible so you always know
|
|
2037
2041
|
which organism this workspace belongs to. */
|
|
2038
|
-
.pj-ws-crumbs { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.2rem; }
|
|
2039
|
-
.pj-crumb-sep { color: var(--muted); font-size: 0.85rem; }
|
|
2040
|
-
.pj-crumb-org { font-size: 0.85rem; font-weight: 600; color: var(--text); }
|
|
2041
2042
|
|
|
2042
2043
|
/* Title row — workspace name + status badge sit on one line. */
|
|
2043
2044
|
.pj-ws-titlerow { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
|
|
@@ -2106,6 +2107,11 @@
|
|
|
2106
2107
|
.pj-field { display: flex; flex-direction: column; gap: 0.2rem; margin-bottom: 0.35rem; }
|
|
2107
2108
|
.pj-field > span { font-size: 0.75rem; color: var(--muted); }
|
|
2108
2109
|
.pj-field-inline { flex-direction: row; align-items: center; gap: 0.4rem; }
|
|
2110
|
+
/* SchemaForm: per-field hint text + missing-required highlight after a Save attempt. */
|
|
2111
|
+
.pj-field-hint { font-size: 0.72rem; color: var(--muted); margin-top: -0.1rem; }
|
|
2112
|
+
.pj-field-invalid > span:first-child { color: var(--danger); }
|
|
2113
|
+
.pj-field-invalid .input-field { border-color: var(--danger); }
|
|
2114
|
+
.pj-form-error { font-size: 0.82rem; color: var(--danger); padding: 0.3rem 0; }
|
|
2109
2115
|
.pj-errors { border: 1px solid var(--danger); border-radius: 10px; padding: 0.6rem 0.75rem; margin: 0.5rem 0; background: var(--bg-dim); }
|
|
2110
2116
|
.pj-errors-title { font-weight: 600; margin-bottom: 0.3rem; color: var(--danger); }
|
|
2111
2117
|
.pj-error-line { font-size: 0.82rem; color: var(--text); padding: 0.1rem 0; }
|
|
@@ -2382,3 +2388,61 @@
|
|
|
2382
2388
|
.pj-org-tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }
|
|
2383
2389
|
.pj-org-tab-count { color: var(--muted); font-size: 0.75rem; margin-left: 0.3rem; }
|
|
2384
2390
|
.pj-org-boardrow { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
|
|
2391
|
+
|
|
2392
|
+
/* ── Workspace renew (phase 2): header actions, review banner, add-space tab ── */
|
|
2393
|
+
.pj-ws-head-actions { margin-left: auto; display: flex; gap: 0.4rem; align-items: center; }
|
|
2394
|
+
.pj-ws-banner { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; border: 1px solid var(--border); border-left: 3px solid var(--warn, var(--accent)); border-radius: 10px; background: var(--card); padding: 0.55rem 0.75rem; margin: 0.6rem 0 0.2rem; }
|
|
2395
|
+
.pj-ws-banner-text { flex: 1; min-width: 200px; font-size: 0.85rem; color: var(--text); }
|
|
2396
|
+
.pj-ws-banner-sub { display: block; font-size: 0.76rem; color: var(--muted); }
|
|
2397
|
+
.pj-ws-tab-add { font-weight: 700; padding: 0.45rem 0.45rem; }
|
|
2398
|
+
|
|
2399
|
+
/* ── Organism home tab contents (feedback round): tab headers, pills, agent picker, board preview ── */
|
|
2400
|
+
.pj-tabhead { display: flex; align-items: flex-start; gap: 0.6rem; margin-bottom: 0.6rem; }
|
|
2401
|
+
.pj-tabhead-desc { flex: 1; margin: 0.2rem 0 0; }
|
|
2402
|
+
.pj-tab-pill { display: inline-block; background: var(--warn-bg, var(--bg-dim)); color: var(--warn-fg, var(--text)); border: 1px solid var(--warn-border, var(--border)); border-radius: 999px; font-size: 0.7rem; padding: 0.05rem 0.5rem; margin-left: 0.35rem; white-space: nowrap; }
|
|
2403
|
+
.pj-org-main-static { cursor: default; }
|
|
2404
|
+
.pj-linklike { background: none; border: none; padding: 0.2rem 0; font-size: 0.78rem; color: var(--accent); cursor: pointer; text-align: left; }
|
|
2405
|
+
.pj-linklike:hover { text-decoration: underline; }
|
|
2406
|
+
.pj-attach { border: 1px solid var(--border); border-radius: 10px; background: var(--bg-dim); padding: 0.6rem 0.75rem; margin-bottom: 0.6rem; display: flex; flex-direction: column; gap: 0.4rem; }
|
|
2407
|
+
.pj-invite-row { margin-bottom: 0.6rem; }
|
|
2408
|
+
.pj-req-row { border-left: 3px solid var(--warn, var(--accent)); margin-bottom: 0.5rem; }
|
|
2409
|
+
.pj-orgsearch { margin: 0 0 0.6rem; }
|
|
2410
|
+
.pj-orgsearch-input { min-width: 220px; }
|
|
2411
|
+
.pj-board-post { border: 1px solid var(--border); border-radius: 10px; background: var(--card); padding: 0.5rem 0.7rem; margin-bottom: 0.5rem; }
|
|
2412
|
+
.pj-board-post-head { display: flex; align-items: baseline; gap: 0.5rem; margin-bottom: 0.2rem; }
|
|
2413
|
+
.pj-board-author { font-weight: 600; font-size: 0.82rem; color: var(--text); }
|
|
2414
|
+
.pj-board-time { font-size: 0.74rem; color: var(--muted); }
|
|
2415
|
+
.pj-board-body { font-size: 0.85rem; color: var(--text); white-space: pre-wrap; word-break: break-word; }
|
|
2416
|
+
.pj-board-composer { margin-top: 0.6rem; }
|
|
2417
|
+
.pj-board-input { flex: 1; min-width: 220px; }
|
|
2418
|
+
|
|
2419
|
+
/* ── Organism settings form (labels, groups, hints, tag input, separated danger zone) ── */
|
|
2420
|
+
.pj-meta-line { display: flex; flex-wrap: wrap; gap: 0.25rem 0; font-size: 0.78rem; color: var(--muted); margin-bottom: 0.8rem; align-items: center; }
|
|
2421
|
+
.pj-meta-line > span + span::before { content: '·'; margin: 0 0.45rem; color: var(--muted); }
|
|
2422
|
+
.pj-form-group { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin: 0.9rem 0 0.45rem; }
|
|
2423
|
+
.pj-form-row { display: flex; gap: 0.75rem; flex-wrap: wrap; }
|
|
2424
|
+
.pj-form-row > .pj-field { flex: 1; min-width: 160px; }
|
|
2425
|
+
.pj-form-hint { font-size: 0.76rem; color: var(--muted); margin: 0.1rem 0 0.5rem; }
|
|
2426
|
+
.pj-taginput { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; border: 1.5px solid var(--control-border); border-radius: var(--radius); background: var(--control-bg); padding: 0.3rem 0.45rem; }
|
|
2427
|
+
.pj-tag { display: inline-flex; align-items: center; gap: 0.25rem; }
|
|
2428
|
+
.pj-tag-x { background: none; border: none; cursor: pointer; color: var(--muted); font-size: 0.85rem; padding: 0 0.1rem; line-height: 1; }
|
|
2429
|
+
.pj-tag-x:hover { color: var(--danger); }
|
|
2430
|
+
.pj-taginput-field { flex: 1; min-width: 90px; border: none; background: transparent; color: var(--text); font-size: 0.82rem; outline: none; padding: 0.15rem 0; }
|
|
2431
|
+
.pj-danger-box { margin-top: 1.1rem; margin-bottom: 0.75rem; }
|
|
2432
|
+
.pj-danger-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
|
|
2433
|
+
.pj-danger-text { flex: 1; min-width: 220px; }
|
|
2434
|
+
.pj-danger-sub { font-size: 0.78rem; color: var(--muted); }
|
|
2435
|
+
.pj-danger-confirm { margin-top: 0.6rem; display: flex; gap: 0.5rem; align-items: flex-end; flex-wrap: wrap; }
|
|
2436
|
+
.pj-members-cap { font-size: 0.74rem; color: var(--muted); }
|
|
2437
|
+
|
|
2438
|
+
/* ── Workspace row: clickable participants counter + inline people list ── */
|
|
2439
|
+
.pj-stat-btn { background: none; border: none; cursor: pointer; padding: 0.1rem 0.3rem; border-radius: 6px; font-size: 0.78rem; color: var(--muted); }
|
|
2440
|
+
.pj-stat-btn:hover { background: var(--bg-surface); color: var(--text); }
|
|
2441
|
+
.pj-stat-btn.active { background: var(--bg-dim); color: var(--text); }
|
|
2442
|
+
.pj-ws-person { display: flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0; font-size: 0.83rem; color: var(--text); }
|
|
2443
|
+
.pj-ws-person-agents { font-size: 0.76rem; color: var(--muted); }
|
|
2444
|
+
|
|
2445
|
+
/* ── Settings polish: menu divider, bounded form card ── */
|
|
2446
|
+
.pj-menu-sep { height: 1px; background: var(--border); margin: 0.25rem 0.3rem; }
|
|
2447
|
+
.pj-form-card { border: 1px solid var(--border); border-radius: 10px; background: var(--card); padding: 0.75rem 0.9rem 0.6rem; margin-bottom: 0.25rem; }
|
|
2448
|
+
.pj-form-card .pj-form-group:first-child { margin-top: 0; }
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* (a "project" is just an organism with a meta.manifest): apply a
|
|
5
|
-
* read the workspace, write/publish drafts, and
|
|
2
|
+
* @file organisms.js
|
|
3
|
+
* @description AIMEAT Organisms Service — organism CRUD, membership, join requests, and the
|
|
4
|
+
* manifest-driven workspace (a "project" is just an organism with a meta.manifest): apply a
|
|
5
|
+
* template, generate a workspace with AI, read the workspace, write/publish drafts, and
|
|
6
|
+
* resolve gate approvals.
|
|
7
|
+
* @usage import * as orgService from '/js/services/organisms.js';
|
|
8
|
+
* @version-history
|
|
9
|
+
* v1.1.0 — 2026-06-10 — Generator prompt: per-property "description", "readOnly": true for
|
|
10
|
+
* agent-filled result fields (never required), "x-default": "currentUser" for requester
|
|
11
|
+
* fields, and a manifest "i18n" block (en + request language) with flat "{ns}.{field}",
|
|
12
|
+
* "{ns}.{field}.hint" and "type.{name}" labels the workspace UI renders.
|
|
6
13
|
*/
|
|
7
14
|
import { api, apiGet, apiPost, apiPut, apiPatch, apiDelete } from '/js/api.js';
|
|
8
15
|
|
|
@@ -235,6 +242,7 @@ Respond with this shape:
|
|
|
235
242
|
"kind": "<short-kebab-case kind, e.g. game-dev>",
|
|
236
243
|
"status": "active",
|
|
237
244
|
"objectTypes": [ <one entry per type> ],
|
|
245
|
+
"i18n": { <UI labels per language — see below> },
|
|
238
246
|
"policy": { "agentAutonomy": "L3", "alwaysGate": [] }
|
|
239
247
|
},
|
|
240
248
|
"schemas": { <one JSON Schema per RECORDS type, keyed by that type's namespace> },
|
|
@@ -254,6 +262,17 @@ Give every objectType all of these fields:
|
|
|
254
262
|
For each RECORDS type, add a JSON Schema under "schemas" keyed by its namespace:
|
|
255
263
|
{ "type": "object", "required": ["id", ...], "properties": { "id": { "type": "string" }, ... } }
|
|
256
264
|
Give every record an "id" string property. Use "enum" for status-like fields and "format": "date" (or "date-time") for date fields.
|
|
265
|
+
Also, for each property:
|
|
266
|
+
- Give every property except "id" a short English "description" telling a human what to fill in.
|
|
267
|
+
- Result fields that an agent or automation fills later (e.g. result_ref, output links, error details) get "readOnly": true — the form hides them from humans. Never list a readOnly field in "required".
|
|
268
|
+
- Fields that should default to the acting user's identity (e.g. requested_by, created_by, author) get "x-default": "currentUser".
|
|
269
|
+
|
|
270
|
+
Inside "manifest", add an "i18n" object with UI labels: one entry per language — always "en", plus the language of the user's request if different. Keys are flat strings:
|
|
271
|
+
- "<namespace>.<field>": a short human label for that field
|
|
272
|
+
- "<namespace>.<field>.hint": one short sentence telling the user what to enter
|
|
273
|
+
- "type.<objectType name>": a short plural label for that type's tab
|
|
274
|
+
Example: "i18n": { "en": { "shared.milestones.title": "Title", "shared.milestones.title.hint": "A short name for the milestone", "type.milestone": "Milestones" }, "fi": { "shared.milestones.title": "Otsikko", "shared.milestones.title.hint": "Lyhyt nimi virstanpylväälle", "type.milestone": "Virstanpylväät" } }
|
|
275
|
+
Cover every field of every RECORDS type (labels + hints) and every objectType (type.<name>) in every language you include.
|
|
257
276
|
|
|
258
277
|
For each DOCUMENT type, the content is free markdown — keep it out of "schemas" and "examples" (a document needs neither).
|
|
259
278
|
|
|
@@ -267,10 +286,14 @@ Worked example — request "track game milestones plus free-form design docs":
|
|
|
267
286
|
{ "name": "milestone", "schemaRef": "schema:milestone@1", "namespace": "shared.milestones", "backing": "memory", "writeRole": "member", "cardinality": "many", "versioned": true, "mode": "records" },
|
|
268
287
|
{ "name": "design-doc", "schemaRef": "schema:design-doc@1", "namespace": "shared.design-docs", "backing": "memory", "writeRole": "member", "cardinality": "many", "versioned": true, "mode": "document" }
|
|
269
288
|
],
|
|
289
|
+
"i18n": {
|
|
290
|
+
"en": { "type.milestone": "Milestones", "type.design-doc": "Design docs", "shared.milestones.title": "Title", "shared.milestones.title.hint": "A short name for the milestone", "shared.milestones.status": "Status", "shared.milestones.status.hint": "Where this milestone stands", "shared.milestones.due_date": "Due date", "shared.milestones.due_date.hint": "When this should be done" },
|
|
291
|
+
"fi": { "type.milestone": "Virstanpylväät", "type.design-doc": "Suunnitteludokumentit", "shared.milestones.title": "Otsikko", "shared.milestones.title.hint": "Lyhyt nimi virstanpylväälle", "shared.milestones.status": "Tila", "shared.milestones.status.hint": "Missä vaiheessa tämä on", "shared.milestones.due_date": "Määräpäivä", "shared.milestones.due_date.hint": "Milloin tämän pitäisi olla valmis" }
|
|
292
|
+
},
|
|
270
293
|
"policy": { "agentAutonomy": "L3", "alwaysGate": [] }
|
|
271
294
|
},
|
|
272
295
|
"schemas": {
|
|
273
|
-
"shared.milestones": { "type": "object", "required": ["id", "title", "status"], "properties": { "id": { "type": "string" }, "title": { "type": "string" }, "status": { "type": "string", "enum": ["planned", "in-progress", "done"] }, "due_date": { "type": "string", "format": "date" } } }
|
|
296
|
+
"shared.milestones": { "type": "object", "required": ["id", "title", "status"], "properties": { "id": { "type": "string" }, "title": { "type": "string", "description": "A short name for the milestone" }, "status": { "type": "string", "enum": ["planned", "in-progress", "done"], "description": "Where this milestone stands" }, "due_date": { "type": "string", "format": "date", "description": "When this should be done" } } }
|
|
274
297
|
},
|
|
275
298
|
"examples": {
|
|
276
299
|
"shared.milestones": [ { "id": "example-1", "title": "Vertical slice", "status": "planned", "due_date": "2026-09-01" } ]
|