@songsid/agend 2.3.2-beta.10 → 2.3.2-beta.12

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.
Files changed (132) hide show
  1. package/README.md +4 -0
  2. package/README.zh-TW.md +4 -0
  3. package/dist/agent-cli.js +48 -0
  4. package/dist/agent-cli.js.map +1 -1
  5. package/dist/agent-endpoint.js +6 -0
  6. package/dist/agent-endpoint.js.map +1 -1
  7. package/dist/agent-whats-new.js +3 -0
  8. package/dist/agent-whats-new.js.map +1 -1
  9. package/dist/backend/kiro-classic-archive.d.ts +52 -0
  10. package/dist/backend/kiro-classic-archive.js +444 -0
  11. package/dist/backend/kiro-classic-archive.js.map +1 -0
  12. package/dist/backend/kiro-identity.d.ts +19 -0
  13. package/dist/backend/kiro-identity.js +43 -0
  14. package/dist/backend/kiro-identity.js.map +1 -1
  15. package/dist/backend/kiro-migration-verify.d.ts +10 -0
  16. package/dist/backend/kiro-migration-verify.js +52 -0
  17. package/dist/backend/kiro-migration-verify.js.map +1 -0
  18. package/dist/backend/kiro-v2-store-worker.js +21 -1
  19. package/dist/backend/kiro-v2-store-worker.js.map +1 -1
  20. package/dist/backend/kiro-v2-store.d.ts +8 -0
  21. package/dist/backend/kiro-v2-store.js.map +1 -1
  22. package/dist/backend/kiro.d.ts +99 -1
  23. package/dist/backend/kiro.js +352 -18
  24. package/dist/backend/kiro.js.map +1 -1
  25. package/dist/backend/types.d.ts +49 -0
  26. package/dist/backend/types.js +9 -0
  27. package/dist/backend/types.js.map +1 -1
  28. package/dist/channel/ipc-timeouts.js +3 -0
  29. package/dist/channel/ipc-timeouts.js.map +1 -1
  30. package/dist/channel/mcp-tools.js +12 -0
  31. package/dist/channel/mcp-tools.js.map +1 -1
  32. package/dist/cli.js +33 -0
  33. package/dist/cli.js.map +1 -1
  34. package/dist/config-validator.js +2 -0
  35. package/dist/config-validator.js.map +1 -1
  36. package/dist/config.js +2 -0
  37. package/dist/config.js.map +1 -1
  38. package/dist/daemon.d.ts +45 -0
  39. package/dist/daemon.js +342 -19
  40. package/dist/daemon.js.map +1 -1
  41. package/dist/dashboard-permissions.d.ts +15 -4
  42. package/dist/dashboard-permissions.js +49 -23
  43. package/dist/dashboard-permissions.js.map +1 -1
  44. package/dist/fleet-control-audit.d.ts +1 -1
  45. package/dist/fleet-control-audit.js +3 -0
  46. package/dist/fleet-control-audit.js.map +1 -1
  47. package/dist/fleet-manager.d.ts +61 -2
  48. package/dist/fleet-manager.js +421 -28
  49. package/dist/fleet-manager.js.map +1 -1
  50. package/dist/general-knowledge/skills/docker-install/SKILL.md +25 -0
  51. package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +10 -0
  52. package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +28 -0
  53. package/dist/general-knowledge/skills/web-appearance/SKILL.md +28 -0
  54. package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +20 -2
  55. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +20 -2
  56. package/dist/instance-config-impact.js +2 -2
  57. package/dist/instance-config-impact.js.map +1 -1
  58. package/dist/instance-lifecycle.d.ts +4 -0
  59. package/dist/instance-lifecycle.js +7 -0
  60. package/dist/instance-lifecycle.js.map +1 -1
  61. package/dist/kiro-migrate.d.ts +11 -0
  62. package/dist/kiro-migrate.js +86 -31
  63. package/dist/kiro-migrate.js.map +1 -1
  64. package/dist/kiro-session-proof.d.ts +41 -0
  65. package/dist/kiro-session-proof.js +89 -0
  66. package/dist/kiro-session-proof.js.map +1 -0
  67. package/dist/kiro-tui-forensic.d.ts +5 -0
  68. package/dist/kiro-tui-forensic.js +3 -3
  69. package/dist/kiro-tui-forensic.js.map +1 -1
  70. package/dist/locale.js +142 -0
  71. package/dist/locale.js.map +1 -1
  72. package/dist/log-service.js +1 -1
  73. package/dist/log-service.js.map +1 -1
  74. package/dist/needs-you.d.ts +3 -1
  75. package/dist/needs-you.js +4 -2
  76. package/dist/needs-you.js.map +1 -1
  77. package/dist/office-share.d.ts +12 -2
  78. package/dist/office-share.js +27 -2
  79. package/dist/office-share.js.map +1 -1
  80. package/dist/outbound-schemas.d.ts +39 -0
  81. package/dist/outbound-schemas.js +29 -0
  82. package/dist/outbound-schemas.js.map +1 -1
  83. package/dist/remote-card-prompt.d.ts +38 -0
  84. package/dist/remote-card-prompt.js +86 -0
  85. package/dist/remote-card-prompt.js.map +1 -0
  86. package/dist/settings-change.js +8 -5
  87. package/dist/settings-change.js.map +1 -1
  88. package/dist/settings-instance-patch.js +1 -1
  89. package/dist/settings-instance-patch.js.map +1 -1
  90. package/dist/tool-permissions.js +17 -0
  91. package/dist/tool-permissions.js.map +1 -1
  92. package/dist/transcript-sources.d.ts +1 -0
  93. package/dist/transcript-sources.js +2 -1
  94. package/dist/transcript-sources.js.map +1 -1
  95. package/dist/types.d.ts +5 -0
  96. package/dist/ui/chat-store.js +3 -2
  97. package/dist/ui/chat-strings.js +2 -2
  98. package/dist/ui/fleet-office-editor.js +54 -2
  99. package/dist/ui/fleet-office-layout.js +44 -7
  100. package/dist/ui/fleet-office-pack.d.ts +9 -3
  101. package/dist/ui/fleet-office-pack.js +117 -19
  102. package/dist/ui/fleet-office-store.js +43 -0
  103. package/dist/ui/fleet-office-zones.js +92 -17
  104. package/dist/ui/fleet-office.js +102 -16
  105. package/dist/ui/panel-chat.js +14 -2
  106. package/dist/ui/panel-log.js +2 -2
  107. package/dist/ui/panel-needs.js +1 -1
  108. package/dist/ui/panel-settings.js +5 -5
  109. package/dist/ui/settings-model.js +17 -9
  110. package/dist/ui/settings-strings.js +2 -0
  111. package/dist/ui/shared/app-i18n.js +2 -2
  112. package/dist/ui/shared/app-stream.js +1 -1
  113. package/dist/ui/shared/app.css +18 -2
  114. package/dist/web-api.d.ts +5 -1
  115. package/dist/web-api.js +91 -3
  116. package/dist/web-api.js.map +1 -1
  117. package/dist/web-office-acts.js +2 -2
  118. package/dist/web-office-acts.js.map +1 -1
  119. package/dist/web-office-pack-read.d.ts +35 -0
  120. package/dist/web-office-pack-read.js +252 -0
  121. package/dist/web-office-pack-read.js.map +1 -0
  122. package/dist/web-office-pack-tools.d.ts +232 -0
  123. package/dist/web-office-pack-tools.js +754 -0
  124. package/dist/web-office-pack-tools.js.map +1 -0
  125. package/dist/web-office-skins.d.ts +68 -4
  126. package/dist/web-office-skins.js +318 -33
  127. package/dist/web-office-skins.js.map +1 -1
  128. package/dist/web-office-store.d.ts +21 -2
  129. package/dist/web-office-store.js +78 -18
  130. package/dist/web-office-store.js.map +1 -1
  131. package/package.json +1 -1
  132. package/templates/windows-shortcuts.ps1 +16 -15
@@ -873,6 +873,9 @@ img.amb-p { object-fit: contain; }
873
873
  .st-link:hover { text-decoration-thickness: 2px; }
874
874
  .prompt .acts { display: flex; gap: var(--s-2); margin-top: var(--s-2); align-items: center; flex-wrap: wrap; }
875
875
  .prompt .wait { font-size: var(--fs-xs); color: var(--text-3); }
876
+ /* #2675: a prompt's typed answer. 16px keeps iOS from zooming in on focus (#1612). */
877
+ .prompt .prompt-text { display: flex; gap: var(--s-2); margin-top: var(--s-2); }
878
+ .prompt .prompt-text input { flex: 1; min-width: 0; font-size: 16px; }
876
879
  .work-bar { display: flex; gap: var(--s-2); align-items: center; padding: 0 var(--s-2); font-size: var(--fs-sm); color: var(--text-2); }
877
880
  .work-bar .lbl { flex: 1; min-width: 0; }
878
881
  .work-bar .pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); animation: pulse 1.2s ease-in-out infinite; flex-shrink: 0; }
@@ -1852,6 +1855,10 @@ html.oo-immersive .p-fleet > .panel-body { z-index: 50; }
1852
1855
  .ol-night > circle { fill: var(--surface); fill-opacity: 0.85; }
1853
1856
  .ol-night > .ol-moon { fill: var(--warn); stroke: none; pointer-events: none; }
1854
1857
  .ol-night-line { stroke: var(--warn); stroke-width: 1.5; stroke-dasharray: 4 3; stroke-opacity: 0.8; pointer-events: none; }
1858
+ /* #2691: a reserved seat — a dashed ring round its dot; the selected seat's "Reserved for" picks. */
1859
+ .ol-seat > .ol-for-ring { fill: none; stroke: var(--warn); stroke-width: 2; stroke-dasharray: 3 3; pointer-events: none; }
1860
+ .ol-for { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px var(--s-2); }
1861
+ .ol-for > legend { float: left; margin-right: var(--s-2); }
1855
1862
  .ol-waypoint > circle { fill: var(--focus); }
1856
1863
  .ol-handle.on > circle, .ol-handle.on > rect, .ol-handle:focus-visible > circle, .ol-handle:focus-visible > rect { stroke: var(--focus); stroke-width: 4; }
1857
1864
  .ol-bar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 8; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); padding: var(--s-2);
@@ -1863,14 +1870,23 @@ html.oo-immersive .p-fleet > .panel-body { z-index: 50; }
1863
1870
  .ol-corridors { display: inline-flex; flex-wrap: wrap; gap: 4px; }
1864
1871
  .ol-msg { flex-basis: 100%; margin: 0; }
1865
1872
  @media (max-width: 640px) {
1866
- /* A phone: the bars at the column's narrower padding; the stage at least most of a screen; no overview (as the canvas). */
1873
+ /* A phone: the bars at the column's narrower padding; no overview (as the canvas). #2689: the stage takes the panel's
1874
+ height that is left under the bars (the column, .oc-office and .oo grow into it) and no more, so zoomed in the
1875
+ scene's bottom is on screen: a floor fixed to the window (100dvh less a guess at the bars) put it under the tab bar
1876
+ once the bars wrapped. Its own floor is low enough for a 375 × 667 phone with the Office bar on five rows (215 px
1877
+ left); only a shorter screen scrolls the panel (on the bars: the stage's touches are its own). */
1867
1878
  .oc-office > .oc-bar { padding: var(--s-2) var(--s-3); }
1868
1879
  .oc-office > .oc-legend { margin: 0 var(--s-3) var(--s-2); }
1869
1880
  .oo > :not(.oo-stage):not(dialog) { margin-left: var(--s-3); margin-right: var(--s-3); }
1870
- .oo-stage { min-height: max(300px, calc(100dvh - 300px)); }
1881
+ .oo-stage { min-height: 200px; }
1871
1882
  .oo-pick .tb-select { max-width: 150px; }
1872
1883
  .oo-mini { display: none; }
1873
1884
  .oo-zoom .icon-btn { width: 40px; height: 40px; }
1885
+ /* #2689: a column of the label and five 40 px buttons (~240 px) is taller than that stage: a row along its top
1886
+ instead, out of fullscreen (there the stage is the screen, and the office switcher is on the left of its top). */
1887
+ .oo:not(.fs) .oo-zoom { flex-direction: row; }
1888
+ .oo:not(.fs) .oo-zoom-pct { display: flex; align-items: center; padding: 0 6px; border-bottom: 0; border-right: 1px solid var(--border); }
1889
+ .oo:not(.fs) .oo-zoom .icon-btn + .icon-btn { border-top: 0; border-left: 1px solid var(--border); }
1874
1890
  }
1875
1891
  /* A phone: Fleet's five tabs fit when only the open one shows its label (the others keep theirs for screen readers). */
1876
1892
  @media (max-width: 479px) {
package/dist/web-api.d.ts CHANGED
@@ -11,6 +11,7 @@ import type { ThemeStore } from "./web-theme-store.js";
11
11
  import type { OfficeStore, OfficeWriteLimiter } from "./web-office-store.js";
12
12
  import { type OfficeSkinStore } from "./web-office-skins.js";
13
13
  import type { OfficeActs } from "./web-office-acts.js";
14
+ import type { OfficePackTools } from "./web-office-pack-tools.js";
14
15
  import type { WebAppearance } from "./web-appearance.js";
15
16
  import type { SendOpts } from "./channel/types.js";
16
17
  import type { IncomingMessage, ServerResponse } from "node:http";
@@ -214,6 +215,8 @@ export interface WebApiContext {
214
215
  };
215
216
  /** #2636: a share was made or ended from the page — said in General (who, which office, until when). */
216
217
  officeShareNotice?(event: "created" | "revoked", who: string, share: import("./office-share.js").OfficeShare | null, count: number): void;
218
+ /** #2692: the agents' skin-pack changes (approval mode, pending changes, log); absent: /ui/office-pack-changes is not offered. */
219
+ readonly officePackTools?: Pick<OfficePackTools, "changes" | "setApproval" | "decide">;
217
220
  /** #2513: the Office view's uploaded skin packs (web-office-skins/); absent: /ui/office-skins is not offered. */
218
221
  readonly officeSkins?: OfficeSkinStore;
219
222
  /** How often a person may upload or delete a skin pack (absent: no limit). */
@@ -324,7 +327,8 @@ export interface WebApiContext {
324
327
  message: string;
325
328
  };
326
329
  /** Answer one of them, exactly as a click on its platform button would. */
327
- clickWebPrompt?(instance: string, nonce: string, action: string): Promise<{
330
+ /** `text`: #2675 — the typed answer, for the one action the page shows a text box for. */
331
+ clickWebPrompt?(instance: string, nonce: string, action: string, text?: string): Promise<{
328
332
  status: number;
329
333
  error?: string;
330
334
  }>;
package/dist/web-api.js CHANGED
@@ -672,6 +672,92 @@ function handleOfficeSkins(req, res, url, ctx, path, method) {
672
672
  });
673
673
  return true;
674
674
  }
675
+ /**
676
+ * #2692: the agents' skin-pack changes, for the Office page (Edit offices → Skin packs) — an admin session only, never
677
+ * the CLI token, a guest or the public link (as uploading a pack by hand). GET { approval, agents, pending, log };
678
+ * POST { approval: "apply" | "approve" } sets the fleet's approval mode; POST /<id> { decision: "approve" | "reject" }
679
+ * decides a pending change (judged again on a yes). Every change is `office_pack_changes` on the stream.
680
+ */
681
+ function handleOfficePackChanges(req, res, url, ctx, path, method) {
682
+ const tools = ctx.officePackTools;
683
+ if (!tools) {
684
+ json(res, 404, { error: "Pack changes are not kept on this fleet" });
685
+ return true;
686
+ }
687
+ const one = /^\/ui\/office-pack-changes\/([0-9a-f]{32})$/.exec(path);
688
+ if (!(method === "GET" && path === "/ui/office-pack-changes") && !(method === "POST" && (path === "/ui/office-pack-changes" || one))) {
689
+ json(res, 404, { error: "not found" });
690
+ return true;
691
+ }
692
+ if (gatewayRequestContext(req)) {
693
+ json(res, 403, { error: "pack_changes_not_over_public_link" });
694
+ return true;
695
+ }
696
+ const who = () => {
697
+ const verdict = evaluateWebRequest(req, url, ctx.webToken ?? null, ctx.webSessions, { touch: false });
698
+ if (verdict.kind !== "allow")
699
+ return { status: 401 };
700
+ return verdict.via === "session" && verdict.session?.tier === "admin" ? { person: verdict.session.owner ? webPersonKey(verdict.session.owner) : "admin-session" } : { status: 403 };
701
+ };
702
+ const refuse = (status) => json(res, status, { error: status === 401 ? WEB_TOKEN_INVALID_MESSAGE : "pack_changes_need_an_admin_session" });
703
+ const first = who();
704
+ if ("status" in first) {
705
+ refuse(first.status);
706
+ return true;
707
+ }
708
+ if (method === "GET") {
709
+ res.setHeader("Cache-Control", "private, no-store");
710
+ json(res, 200, tools.changes());
711
+ return true;
712
+ }
713
+ (async () => {
714
+ let body;
715
+ try {
716
+ body = await parseBody(req);
717
+ }
718
+ catch {
719
+ json(res, 400, { error: "Invalid JSON" });
720
+ return;
721
+ }
722
+ if (!permitWebContinuation(req, res, ctx))
723
+ return;
724
+ const now = who();
725
+ if ("status" in now) {
726
+ refuse(now.status);
727
+ return;
728
+ }
729
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
730
+ json(res, 400, { error: "an object" });
731
+ return;
732
+ }
733
+ if (!one) {
734
+ if (Object.keys(body).some(k => k !== "approval")) {
735
+ json(res, 400, { error: "pack_changes_invalid", detail: "{ approval }" });
736
+ return;
737
+ }
738
+ const r = tools.setApproval(body.approval, now.person);
739
+ if (!r.ok) {
740
+ json(res, 400, { error: "pack_changes_invalid", detail: r.error });
741
+ return;
742
+ }
743
+ json(res, 200, tools.changes());
744
+ return;
745
+ }
746
+ if (Object.keys(body).some(k => k !== "decision") || (body.decision !== "approve" && body.decision !== "reject")) {
747
+ json(res, 400, { error: "pack_changes_invalid", detail: '{ decision: "approve" | "reject" }' });
748
+ return;
749
+ }
750
+ const r = tools.decide(one[1], body.decision, now.person);
751
+ json(res, r.ok ? 200 : r.status, r.ok ? { text: r.text, ...(r.applied ? { applied: r.applied } : {}) } : { error: r.error, detail: r.text });
752
+ })().catch(err => {
753
+ ctx.logger.error({ err: err.message }, "A pack change failed");
754
+ try {
755
+ json(res, 500, { error: "A pack change failed" });
756
+ }
757
+ catch { /* already answered */ }
758
+ });
759
+ return true;
760
+ }
675
761
  /**
676
762
  * #1629 r4 §3: the owner-CSS routes (see their call site). `who()`, asked first and again after any body: the person a
677
763
  * signed-in human session is, or the status to answer.
@@ -2411,6 +2497,8 @@ export function handleWebRequest(req, res, url, ctx) {
2411
2497
  }
2412
2498
  if (path === "/ui/office-skins" || path.startsWith("/ui/office-skins/"))
2413
2499
  return handleOfficeSkins(req, res, url, ctx, path, method);
2500
+ if (path === "/ui/office-pack-changes" || path.startsWith("/ui/office-pack-changes/"))
2501
+ return handleOfficePackChanges(req, res, url, ctx, path, method);
2414
2502
  if (path === "/ui/office-share" || path.startsWith("/ui/office-share/"))
2415
2503
  return handleOfficeShare(req, res, url, ctx, path, method);
2416
2504
  // ── #1630: avatars and Discord server emoji, same-origin (the page never loads a platform's CDN; img-src stays 'self') ──
@@ -2500,12 +2588,12 @@ export function handleWebRequest(req, res, url, ctx) {
2500
2588
  json(res, 400, { error: "instance, nonce and action required" });
2501
2589
  return;
2502
2590
  }
2503
- const { instance, nonce, action } = body;
2504
- if (typeof instance !== "string" || typeof nonce !== "string" || typeof action !== "string") {
2591
+ const { instance, nonce, action, text } = body;
2592
+ if (typeof instance !== "string" || typeof nonce !== "string" || typeof action !== "string" || (text !== undefined && typeof text !== "string")) {
2505
2593
  json(res, 400, { error: "instance, nonce and action required" });
2506
2594
  return;
2507
2595
  }
2508
- const r = await click(instance, nonce, action);
2596
+ const r = text === undefined ? await click(instance, nonce, action) : await click(instance, nonce, action, text);
2509
2597
  // 409: answered elsewhere first, expired, or never open — the page drops the buttons on `gone`.
2510
2598
  json(res, r.status, r.status === 200 ? { answered: true } : { error: r.error ?? "Refused", ...(r.status === 409 ? { gone: true } : {}) });
2511
2599
  })().catch(err => {