Commit Graph

12 Commits

Author SHA1 Message Date
claude code agent 227
6edbbab43b refactor(ai): unify provider-settings allowlist + stronger chatApiStyle tests (#177 review)
Addresses the second #177 review:

- Architecture (the silent allowlist drift): the writable provider-setting keys
  were maintained by hand in two TS-uncheckable places — the key-loop in
  ai-settings.service and the SQL ALLOWED list in the generic workspace repo (a
  miss there silently dropped a field on persist, exactly what bit chatApiStyle).
  Introduce one typed source of truth PROVIDER_SETTINGS_KEYS in ai.types
  (`satisfies readonly (keyof AiProviderSettings)[]`), have the service consume
  it, and keep the repo's own copy (it can't import AI types) guarded by a parity
  test so any future drift fails in CI.
- Tests:
  - ai.service.include-usage.spec: mocks @ai-sdk/openai-compatible and asserts the
    factory is called with { includeUsage: true, baseURL, apiKey, fetch, name } —
    `.provider` alone could not catch a dropped includeUsage (the token-usage
    zeroing regression); also asserts the 'openai' style does NOT use it.
  - ai-provider-settings-keys.spec: the allowlist parity check + DTO validation
    for chatApiStyle (@IsIn accepts both values, rejects garbage, optional).
- CHANGELOG: [Unreleased] entries for the new "Protocol" / chatApiStyle setting
  and the default provider change (openai -> openai-compatible). (#175, #177)

server + client tsc clean; 42 ai/settings specs green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 23:18:31 +03:00
claude code agent 227
a0cc625dfe refactor(footnotes): address PR #169 review
- footnote-sync: remove the now-dead `refReids` (CollisionPlan field, local,
  return, the 6a consumer loop) — references are never re-id'd under reuse, so it
  was dead structure on the hot reconciliation path. Rewrite the stale comments
  (plugin header, step 0, refOccurrences field) that still described the old
  "duplicates re-id'd so both survive" model to the reuse model.
- Shared footnote lexer: new packages/mcp/src/lib/footnote-lex.ts
  (lexFootnoteLines + forEachFootnoteReference). extractFootnotes (collaboration)
  and analyzeFootnotes now consume the SAME fence-aware lexer, so "the analyzer
  sees exactly what the importer keeps/strips" is structural, not comment-kept.
  Removed the duplicated DEF_RE/fence machine from both consumers.
- Tests: new mock test for the footnoteWarnings plumbing on createPage (problems
  -> field present; clean -> omitted); new paste-reuse case for TWO colliding
  pasted definitions (reservation -> distinct ids). Updated the derive-id golden
  test header (no MCP copy / parity test anymore).
- CHANGELOG: [Unreleased] entries for footnote reuse (Changed, supersedes 0.93.0)
  and footnoteWarnings (Added).

editor-ext 129, MCP 301, server roundtrip 2; client+server tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 16:16:30 +03:00
8a6ee78c44 Merge pull request 'fix(editor): render NodeViewContent first so click hit-testing isn't offset (#146)' (#147) from fix/146-nodeview-content-order into develop
Reviewed-on: #147
2026-06-24 04:40:59 +03:00
claude_code
8bb441870a test(editor): address PR #147 review — reflow tests, code-block guard, a11y
Resolve the pre-merge review items for the #146 NodeView content-first fix:

- Export collectScrollAncestors/reflowAfterPaste and add editor-paste-handler
  unit tests covering ancestor selection (overlay included, non-overflowing
  auto excluded, X axis), the scrollHeight>clientHeight gate, scrollingElement
  dedup, the docEl==null branch, and the double-rAF nudge.
- Extend the structural guard with CodeBlockView and merge the two it.each
  blocks into one document-order assertion (handles the <pre> nesting where the
  contentDOM is not the literal first child).
- Simplify the post-paste nudge to a single scrollTo(scrollLeft, scrollTop).
- Document that the post-paste reflow runs on every paste path intentionally,
  and cross-reference the two #146 mitigations in both fixes.
- a11y: aria-hidden the decorative footnotes heading and number marker, and
  label the footnotes list via role="group" + aria-label so the visual reorder
  does not break screen-reader reading order (WCAG 1.3.2).
- CHANGELOG: add a Fixed entry noting the caret fix is macOS-verified manually.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 04:36:39 +03:00
claude code agent 227
0647faefcd chore(comments): address PR #143 review (operator doc, badge test, dedup, type)
- [warn 1] Document the is_agent operator setup so it survives plan deletion:
  added an AI-agent block to .env.example (use a DEDICATED account, set is_agent
  via SQL, never flag a human/shared account) + a CHANGELOG "Added" entry.
- [warn 2] Test the badge deep-link side effects: ai-agent-badge.test.tsx now
  renders inside an explicit jotai store, clicks the badge, and asserts the
  active chat id, window-open, cleared draft, closed history modal, AND that
  stopPropagation keeps a parent onClick from firing.
- [suggestion 3] Hoist the window.matchMedia stub into vitest.setup.ts and drop
  the duplicated beforeAll block from the three test files (ai-agent-badge,
  comment-list-item, role-cards).
- [suggestion 4] Merge the two near-duplicate "non-clickable" cases via it.each.
- [follow-up 6] Introduce a single ProvenanceSource = 'user' | 'agent' type in
  jwt-payload.ts and reference it from AuthProvenanceData, JwtPayload/
  JwtCollabPayload, and resolveSource() — so a typo can't slip through as a bare
  string. (Server auth chain; client IComment mirroring left as a follow-up.)

Follow-up 5 (shared agentSourceFields write-stamp helper) is deferred as the
review marked it — the 6 REST sites use varied shapes (create-spread vs
resolve-conditional-null vs page move), so it's a separate focused refactor.

Tests: client badge/comment/role-cards suites 11/11 pass; server auth+comment
suites 62 pass; typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 23:56:26 +03:00
claude_code
ce60498a90 docs: track post-0.93.0 share-AI cap change + deferred stream-coverage debt
Follow-ups from the multi-aspect review of the e5bc82c7..d4658d4c range.

- CHANGELOG: document under [Unreleased] that the default per-workspace
  hourly public-share assistant cap was lowered 300 -> 100 after the
  v0.93.0 tag (#62). v0.93.0 shipped 300, so existing deployments that
  never set SHARE_AI_WORKSPACE_MAX_PER_HOUR drop to 100 on upgrade.
- Recreate the still-open Section 3 (AiChatService.stream integration
  coverage) of the deleted feature-test-coverage-deferred.md as a focused
  backlog doc so the test debt stays tracked; Sections 1-2 are already
  closed by the integration harness (PR #115).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 16:54:56 +03:00
claude_code
06bfca5fdb docs(changelog): 0.93.0 release notes 2026-06-21 14:09:44 +03:00
claude code agent 227
7e26239c3f Merge remote-tracking branch 'gitea/develop' into fix/review-batch-2
# Conflicts:
#	AGENTS.md
#	CHANGELOG.md
#	README.md
#	apps/server/src/collaboration/collaboration.handler.ts
#	apps/server/src/common/helpers/prosemirror/html-embed.spec.ts
#	apps/server/src/common/helpers/prosemirror/html-embed.util.ts
#	apps/server/src/core/ai-chat/public-share-chat.service.ts
#	apps/server/src/core/ai-chat/public-share-chat.spec.ts
#	apps/server/src/core/ai-chat/public-share-workspace-limiter.ts
#	apps/server/src/core/page/services/page.service.ts
#	apps/server/src/core/page/transclusion/transclusion.service.ts
#	apps/server/src/integrations/import/services/file-import-task.service.ts
#	apps/server/src/integrations/import/services/import.service.ts
2026-06-21 05:32:44 +03:00
claude_code
c596e17a40 fix(html-embed): correct stale iframe height and damp the resize loop
Address the non-test code-review findings on the htmlEmbed sandbox change
(test-coverage gaps are tracked in issue #99):

- html-embed-view: track the iframe's reported content height even while a
  fixed height is set, so clearing the height (fixed -> auto) without editing
  the source no longer leaves the frame pinned to the stale value. Derive the
  fixed-height predicate once; seed autoHeight to the default.
- html-embed-view: drop width/border from the iframe inline style (the
  .htmlEmbedFrame CSS class already provides them).
- html-embed-sandbox: coalesce height reports via requestAnimationFrame and
  skip <=1px deltas to damp the self-measure feedback loop; fix the misleading
  bootstrap comment.
- tracker-settings: add an aria-label to the snippet Textarea (a11y).
- CHANGELOG: note the removal of server-side role-based HTML-embed stripping.
2026-06-21 03:50:17 +03:00
claude code agent 227
d45ca00bcc docs(mcp): document the MCP_TOKEN header breaking change + one-time warning (#84)
The shared MCP_TOKEN guard moved from 'Authorization: Bearer <MCP_TOKEN>' to the
X-MCP-Token header (Authorization is now per-user Basic/Bearer), silently breaking
existing /mcp clients. Document it as a Breaking Change in CHANGELOG (reconfigure
to X-MCP-Token). Add a once-per-process migration warning: when MCP_TOKEN is set,
no x-mcp-token is present, and Authorization carries the old 'Bearer <MCP_TOKEN>',
log a hint to migrate — without changing the auth decision (still rejected) or
logging the token value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 03:40:40 +03:00
claude_code
e9ceb0f899 fix(html-embed): address code-review findings on the sandbox commit
Follow-up fixes to the htmlEmbed-sandbox / trackerHead change:

- share-seo: inject trackerHead via a function replacer so `$`-sequences
  ($&, $', $`, $$) in the admin snippet are inserted literally instead of
  being treated as String.replace substitution patterns; warn when the
  </head> marker is absent instead of silently skipping injection.
- mcp: register a passthrough `htmlEmbed` node in the schema mirror so an
  AI/MCP edit of a page containing an embed no longer throws
  "Unknown node type: htmlEmbed" in TiptapTransformer.toYdoc.
- editor-ext + client: treat a non-finite `data-height` as auto (null) so a
  crafted/corrupted height cannot disable auto-resize or yield a NaN iframe
  height; extract a shared clampHeight helper.
- client: rename render-raw-html.{ts,test.ts} -> html-embed-sandbox.{...} and
  shouldExecute -> shouldRender so the seam name matches the sandbox model.
- client: i18n the iframe title; surface the real error reason in
  tracker-settings (console.error + err.response.data.message).
- docs: note hasHtmlEmbedNode is now a test-only helper; add an Unreleased
  CHANGELOG entry; drop the dangling "arbitrary HTML embed" planning-doc ref.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 03:22:37 +03:00
vvzvlad
c6b878c514 0.91.0
Bump root, client and server package versions 0.90.1 -> 0.91.0 to match the
v0.91.0 release tag. packages/mcp keeps its independent 1.0.0 version.
2026-06-18 18:07:54 +03:00