Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4f1fbef
feat(mcp): add pod-mcp, a Model Context Protocol server for Huly
shrijayan Sep 30, 2026
12c8c83
style(mcp): apply repo prettier and eslint formatting
shrijayan Sep 30, 2026
b3b3130
fix(mcp): return 413 for oversized request bodies; document smoke test
shrijayan Sep 30, 2026
5a5b160
fix(mcp): repair tools and auth found by a live smoke test against Huly
shrijayan Sep 30, 2026
d4f3253
feat(mcp): add component, sub-issue and milestone tools; fix nullable…
shrijayan Sep 30, 2026
346b617
feat(mcp): add workspace administration tools backed by the account s…
shrijayan Sep 30, 2026
0afa447
feat(mcp): add generic read tools over any workspace class
shrijayan Sep 30, 2026
bfbf720
feat(mcp): write tools for documents and other profile-backed classes
shrijayan Oct 1, 2026
02e3095
chore(mcp): update lockfile for write-tool dependencies and record fi…
shrijayan Oct 1, 2026
4b50275
fix(mcp): address review blockers on auth, origin and read-only scoping
shrijayan Oct 2, 2026
d1a668c
fix(mcp): address minor review items in issue, write and endpoint paths
shrijayan Oct 2, 2026
e43a9c6
Merge remote-tracking branch 'origin/develop' into feat/tracker-proje…
shrijayan Oct 3, 2026
a9a91ee
feat(tracker): add ProjectField types and validation helpers
shrijayan Oct 3, 2026
4375c80
feat(tracker): add ProjectField model class and Issue.customFields
shrijayan Oct 3, 2026
5c46c70
feat(tracker): enforce field limit and clean values on field removal
shrijayan Oct 3, 2026
4fd4aa8
feat(tracker): custom field management UI, editors and issue panel se…
shrijayan Oct 3, 2026
df9e07d
feat(tracker): custom fields as columns, filter, sort and group-by
shrijayan Oct 3, 2026
a55bf48
feat(tracker): saved views with tabs, per-view config and unsaved-cha…
shrijayan Oct 3, 2026
6d20679
feat(tracker): GitHub-style filter grammar with query bar
shrijayan Oct 3, 2026
f463021
feat(tracker): spreadsheet-style cell editing, paste, fill and undo i…
shrijayan Oct 3, 2026
e73fd25
feat(tracker): iteration fields with settings, filters, grouping and …
shrijayan Oct 3, 2026
1801c9f
fix(tracker): make result narrowing compile under the non-strict prod…
shrijayan Oct 3, 2026
66e5145
feat(tracker): roadmap layout with date fields, markers, zoom and dra…
shrijayan Oct 3, 2026
8fd4fbe
feat(tracker): board column fields, swimlanes, column limits and fiel…
shrijayan Oct 3, 2026
ccb25df
feat(tracker): sub-issue hierarchy, slice-by panel and field sums
shrijayan Oct 3, 2026
c788893
feat(tracker): insights page with configurable current-state charts
shrijayan Oct 3, 2026
77ae309
feat(tracker): archive, built-in workflows and field-change webhooks
shrijayan Oct 3, 2026
b09192d
feat(tracker): project settings, README, status updates, templates an…
shrijayan Oct 3, 2026
0c16552
feat(tracker): draft items, add-item row, view export and view links
shrijayan Oct 3, 2026
0659752
feat(tracker): calendar layout with month, week and agenda modes
shrijayan Oct 3, 2026
eba48be
feat(tracker): workload layout with capacity heatmap and reassignment
shrijayan Oct 3, 2026
624d4e1
feat(tracker): nested grouping across table, board and roadmap views
shrijayan Oct 5, 2026
5f487eb
docs: record phases 0-14, the phase 14 nested grouping notes and the PR
shrijayan Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
14 changes: 14 additions & 0 deletions ARCHITECTURE_OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ sequenceDiagram
| analytics | platformcollective/analytics-collector | 4017 | Analytics collection | account, stats |
| process | platformcollective/process | - | Workflow automation | redpanda, account |
| rating | platformcollective/rating | - | Content rating | cockroach, redpanda, account |
| **AI** | | | | |
| mcp | platformcollective/mcp | 4090 | Model Context Protocol server (Streamable HTTP) | account, transactor, collaborator |
| **Backup** | | | | |
| backup | platformcollective/backup | - | Automated backup | cockroach, minio, account |
| backup-api | platformcollective/backup-api | 4039 | Backup REST API | minio, account |
Expand Down Expand Up @@ -433,6 +435,18 @@ sequenceDiagram
- `QUEUE_CONFIG`: `cockroach|http://redpanda:9092` - Region-based event routing
- `HULY_KAFKA_BOOTSTRAP`: `redpanda:9092` - Kafka bootstrap servers

### MCP Configuration (mcp only)
- `HULY_TOKEN`: Huly API token for the pod's own identity. Setting it selects self-hosted mode, where MCP clients need no Huly credential.
- `HULY_EMAIL` / `HULY_PASSWORD`: Login used when no `HULY_TOKEN` is set
- `HULY_WORKSPACE`: Workspace URL slug or ID the configured account is pinned/scoped to
- `COLLABORATOR_URL`: Collaborator service URL; enables writing rich-text descriptions
- `MCP_ALLOW_DEFAULT_SECRET`: `false` - Dev stacks only; permits `SECRET=secret`
- `MCP_READONLY`: `false` - Refuse every write tool
- `MCP_ALLOWED_TOKENS`: Comma-separated token allowlist for multi-tenant mode
- `MCP_RATE_LIMIT` / `MCP_RATE_WINDOW_MS`: `300` / `60000` - Per-client rate limit

See `pods/mcp/README.md` for the full list.

### Service URLs (Internal)
- `ACCOUNTS_URL`: `http://huly.local:3000`
- `TRANSACTOR_URL`: `ws://huly.local:3332`
Expand Down
138 changes: 137 additions & 1 deletion common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions common/scripts/docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ else
--to @hcengineering/pod-media \
--to @hcengineering/pod-preview \
--to @hcengineering/pod-link-preview \
--to @hcengineering/pod-mcp \
--to @hcengineering/pod-external \
--to @hcengineering/pod-backup \
--to @hcengineering/backup-api-pod \
Expand Down
21 changes: 21 additions & 0 deletions dev/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ services:
ports:
- 4041:4041
restart: unless-stopped
mcp:
image: 'platformcollective/mcp'
extra_hosts:
- 'huly.local:host-gateway'
container_name: mcp
environment:
- SECRET=secret
# The dev stack uses the default platform secret everywhere. pod-mcp refuses it
# unless told this is a throwaway development stack.
- MCP_ALLOW_DEFAULT_SECRET=true
- PORT=4090
- ACCOUNTS_URL=http://huly.local:3000
- COLLABORATOR_URL=http://collaborator:3078
# Set HULY_TOKEN (or HULY_EMAIL + HULY_PASSWORD) to run in self-hosted
# mode. Without it the server expects each MCP client to send its own
# Huly API token, which is not practical from Claude Desktop.
# - HULY_TOKEN=${HULY_TOKEN}
# - HULY_WORKSPACE=${HULY_WORKSPACE}
ports:
- 4090:4090
restart: unless-stopped
cockroach:
image: cockroachdb/cockroach:latest-v24.3
extra_hosts:
Expand Down
105 changes: 105 additions & 0 deletions docs/agentlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Agent log

Append-only. Newest entries at the bottom. Read only the tail if you are continuing work.

## 2026-10-03 — Tracker → GitHub Projects parity: discovery + plan

- Created branch `feat/tracker-projects-parity` off `d1a668cb2`.
- Mapped the tracker feature. Key correction: `plugins/tracker` is declarations only;
all UI lives in `plugins/tracker-resources`, model in `models/tracker`,
generic view infra in `plugins/view` + `plugins/view-resources`.
- Verified the biggest gap: Huly model is **TxModel-fixed**, so user-defined custom
fields cannot be real `core.class.Attribute`s. The `custom*` convention in
`ViewletSetting.svelte:230` is about derived/exported column *labels*, not runtime
attributes. Plan therefore uses a `ProjectField` definition doc + a
`Record<string, any>` shadow prop on `Issue`.
- Verified `ViewOptions.groupBy` is already `string[]` and `groupDepth` exists in
`ViewOptionsModel` but is hardcoded to 1 — nested grouping needs only a real builder.
- Verified `view.class.FilteredView` is already a server-persisted saved view with
`filters` + `viewOptions` + `sharable` + `users`, but is scoped to the workspace
alias, not a project, and cannot carry a column set.
- Plan written to `docs/tracker-projects-parity/plan.md` (8 phases, 7 architecture
decisions, risk table).

## 2026-10-03 — Reconciled GitHub Projects research into the plan (plan REWRITTEN)

Research agent came back with verified corrections (official docs + live GraphQL schema
+ REST + `gh` CLI v2.98.0). Rewrote `plan.md` from scratch. Scope got **smaller and
sharper**, not bigger:

- GitHub has exactly **3 layouts** (Table, Board, Roadmap). No calendar, no gantt-timeline,
no workload. Insights is a separate top-level section, not a layout.
- The view names in the screenshot (Current iteration, Next iteration, Prioritized
backlog, In review, My items) are **NOT GitHub defaults** — GitHub ships none. They are
community/template convention. We ship them as a seeded template.
- **No custom trigger→action automation builder** in GitHub. Only 2 built-in workflows
+ auto-add + auto-archive. Recommending a field-change webhook over a rule engine.
- Exactly **6 custom field types**: TEXT, NUMBER, DATE, SINGLE_SELECT, MULTI_SELECT,
ITERATION. No checkbox, no people, no URL. Max 50 fields/project, 50 options/select.
- No "stack by" / nested grouping. No "Health"/"Priority"/"Estimate"/"Due date" built-ins.
No pie charts (6 layouts: Bar/Column/Stacked bar/Stacked column/Stacked area/Line).
- Export is `.tsv`, not CSV.
- Views are **project-wide and shared** — GitHub has **no personal views**. Dropped the
personal/shared split from the design.

**New highest-leverage decision added — D3: adopt GitHub's filter grammar** (field:/has:/no:/
is:/@me/@today/@current/@next/@previous/ranges a..b/wildcards/AND/OR+parens) as a pure
tokenizer+parser+compiler module, with TWO consumers: server-side string→DocumentQuery, and
client-side evaluation for custom fields the server cannot index. Sharing the tokenizer means
they cannot drift.

**Honest scope cut recorded — D6:** historical Insights charts (X-axis=Time, Open/Completed
series, "Burn up" default) need field-value history that Huly does not have. Options are
replay `DOMAIN_TX` (degrades), snapshot collection (correct, costly), or ship current
charts only. Recommendation: current charts only in v1. Do NOT fake burn-up with TX replay.

Phase list went from 8 to 12 and is now ordered by real dependency: fields(0-1) → views(2)
→ grammar(3) → bulk edit(4) → iterations(5) → roadmap(6) → board(7) → hierarchy/slice/sum(8)
→ insights(9) → workflows(10) → project-level roles(11).

Next: get answers on the 7 open questions in plan.md §8, then time-box Phase 0 as a
2-3 day spike to validate the custom-field-on-record design end to end.

## 2026-10-03 — Phases 0-14 implemented; PR #48 raised

Author resolved the open questions (recorded in plan.md §8): the four dropped extras
(Calendar, Workload, nested grouping, automation builder) **stay in scope** as phases 12-15
because the goal is "the tracker alone is as good as a GitHub board". Roles stay
workspace-level. Historical Insights / burn-up is out. One large PR.

Phases **0-14** are now implemented and committed on `feat/tracker-projects-parity`
(20 commits). Phase 15 (automation rule builder) is deliberately not started — the phase 10
field-change webhook is the parity-faithful route and lands first.

Validation run locally across the 5 changed packages before raising the PR:

```
plugins/tracker-resources tsc --noEmit clean 1215 tests pass (86 suites)
plugins/view-resources tsc --noEmit clean 313 tests pass (16 suites)
models/tracker tsc --noEmit clean 4 tests pass
plugins/view tsc --noEmit clean
plugins/view-assets lang key-parity test passes (14 locales)
```

1533 tests, 0 failures. No formatter run (repo rule).

## 2026-10-03 — Phase 14: nested grouping (the last commit on the branch)

- Table groups up to 3 levels, Board 2 (lane + sub-lane), Roadmap 2. `groupDepth` per viewlet,
and since `builder.createDoc` does not update already-stored viewlet docs, the upgrade step
`set-nested-group-depth` of `model-tracker` patches the existing `IssueList` / `IssueKanban` /
`IssueRoadmap` viewlets. **If a new viewlet is added later, it needs the same treatment.**
- A drop on a board sub-lane writes column + lane + sub-lane in ONE update. Getting that wrong
silently loses the lane value — do not "simplify" it into three writes.
- Collapsed-group state is per viewer AND per saved view, but **only when the view groups on two
or more levels** (single level keeps the legacy key so every other list and the sub-issues of an
issue are unaffected).
- Plan correction recorded in plan.md: `plugins/view-resources/src/utils/nested-groups.ts` listed in
plan section 5 never existed. The real files are `view-resources/src/nestedGroups.ts` (shared list)
and `tracker-resources/src/grouping/` (tracker layouts).
- The old single-level `roadmap/grouping.ts` was deleted; its ordering rules are now covered by the
nested builder tests.

Next: PR #48 is open against `develop`. It is **stacked on `feat/mcp-http-server`**, which has no
PR of its own, so the diff also shows 11 MCP commits that are not part of this effort. Either merge
the MCP work first or review only `git log d1a668cb2..HEAD`. Next work item is phase 15.
Loading
Loading