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.
@@ -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: transparent;
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: none;
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: transparent;
624
- box-shadow: none;
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: transparent;
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: transparent;
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
- * AIMEAT Organisms Service
3
- * Organism CRUD, membership, join requests, and the manifest-driven workspace
4
- * (a "project" is just an organism with a meta.manifest): apply a template,
5
- * read the workspace, write/publish drafts, and resolve gate approvals.
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" } ]