---
title: "Project resource and entry-point inventory"
description: "Local-first visual environment for building and running AI workflows. Build agents visually, deploy anywhere, privacy by design."
canonical: https://docs.nodetool.ai/project-resource-inventory
markdown: https://docs.nodetool.ai/project-resource-inventory.md
product: NodeTool
source: https://github.com/nodetool-ai/nodetool/blob/main/docs/project-resource-inventory.md
---

# Project resource and entry-point inventory

# Project resource and entry-point inventory

This inventory records the project boundary found in source inspection for T1. It is an implementation input for AC11, not a claim that all rows are already scoped.

## Scan evidence

The inventory was produced from the repository with these checks:

```bash
for f in packages/models/src/schema/*.ts; do
  rg -q 'project_id' "$f" && echo "$f"
done
rg -l 'projectId|project_id|useProjects|trpcClient\\.(project|asset|entity|workflow|thread|workspace)' \
  web/src electron/src mobile/src packages/agents/src packages/websocket/src
```

The first scan returned these eight project-bearing tables: `applications`, `assets`, `image_documents`, `js_scripts`, `predictions`, `scripts`, `storyboards`, and `timeline_sequences`. The schema directory also contains non-project tables for `threads`, `messages`, `jobs`, `run_events`, `run_inbox_messages`, `workflows`, `workflow_versions`, and `workspaces`, so the scan found actual candidates outside the current project summary union.

## Resource inventory

| Resource | Storage and current ownership | References and creation paths | List/search paths | Delete behavior | Planned project boundary and migration |
| --- | --- | --- | --- | --- | --- |
| Storyboards | `storyboards.project_id` in `packages/models/src/schema/storyboards.ts`; `Storyboard` model | JSON shot refs include asset refs. Create/update via `packages/websocket/src/trpc/routers/storyboards.ts`, REST timeline/example helpers, and agent `capabilities/storyboards.ts` | `Storyboard.find`, router procedures, `listProjectDocuments` and `summarizeProject` | Model delete and router delete | Project-owned. Keep existing IDs, assign null/legacy rows to Personal. Reads and writes must require the owning project. Copy must remap referenced assets. |
| Scripts | `scripts.project_id`; `Script` model | Script sections and takes reference media and entities. Create/update via `routers/scripts.ts` and agent `capabilities/scripts.ts` | Script router/model and `listProjectDocuments` | Model/router delete | Project-owned. Migrate unassigned rows to Personal. Moving requires checking storyboard/timeline links and preserving or rewriting referenced dependencies. |
| Timelines | `timeline_sequences.project_id`; `TimelineSequence` and version tables | Timeline document contains clip asset refs, script links, and generated outputs. Create/update via `routers/timeline.ts`, REST `routes/timelines.ts`, and agent `capabilities/timelines.ts` | Timeline router/model and `listProjectDocuments` | Model/router delete; versions follow the sequence's document lifecycle | Project-owned. Migrate the sequence and versions together. Copy must include referenced assets and linked project documents or return an unsupported-dependency error. |
| Image documents / sketches | `image_documents.project_id`; `ImageDocument` model | Canvas document and versions reference assets. Create/update via `routers/sketch.ts` and agent `capabilities/sketches.ts` | Sketch router/model and `listProjectDocuments` | Model/router delete; versions follow the document | Project-owned. Migrate document plus versions. Copy needs asset remapping. |
| Applications / mini-app documents | `applications.project_id`; application document may reference workflows/assets. | `routers/applications.ts`, `routes/applications.ts`, `web/src/hooks/useApplications.ts`, mobile `services/api.ts` and `useApplications.ts`, agent `capabilities/apps.ts` | Application router/REST and mobile `listApplications(projectId?)` | Application service/model delete | Project-owned under D3. Migrate existing application rows. Mobile currently supports an optional project filter but defaults to `default`; pass explicit project context on every creation and list. |
| JavaScript scripts | `js_scripts.project_id`; `JsScript` model and versions | Create/update via `routers/js-scripts.ts`, REST `routes/js-scripts.ts`, web sync hook, and agent `capabilities/js-scripts.ts` | Router/model and agent capability | Router/model delete; versions are document-owned | Project-owned. Migrate rows and versions. Agent and web calls need an originating project rather than a default fallback. |
| Entities | Entity marker stored in an asset's `metadata`; entity ownership is `assets.project_id`. | Entity creation/update in agent `capabilities/entities.ts` and `packages/models/src/entity.ts`; web project section and mention picker | `useEntities.ts`, entity capability, `ProjectEntitiesSection.tsx`; entity search currently has a shared-library path | Asset delete; project move uses `moveDocumentToProject(..., "entity", ...)` | Project-owned per D3. Migrate marked assets only. Search, mentions, and agent queries must filter by project. Do not treat unmarked assets as entities. |
| General assets and folders | `nodetool_assets`; `parent_id` forms the asset folder tree. `project_id` defaults to `default`, but current code documents that only entities are shown per project. | Upload/finalize through asset tRPC, REST `routes/assets.ts`, web `AssetStore`, workflow outputs and agent media/binary-output tools. Folder operations use asset parent IDs. | Asset router `list`, `recursive`, `search`, web AssetStore and mobile asset screens | Asset delete removes the asset row and stored file according to asset service behavior | Project-owned under D3, including folders. Migrate every asset and preserve `parent_id` relationships. Define whether generated assets inherit the run's project and make every asset list/search project-scoped. |
| Workflows | `nodetool_workflows` has `workspace_id` but no `project_id`; workflow versions/shares/collaborators also have no project column. | Web workflow manager/editor, mobile graph editor and workflow screens, Electron `api.ts`/preload/tray, REST `routes/workflows.ts`, tRPC workflows router, agent `capabilities/workflows.ts`, imports/templates | Workflow model/router, REST examples/public/tools/name endpoints, mobile and Electron workflow lists | `Workflow.deleteOwned` removes workflow and access grants; workspace deletion refuses linked workflows | Project-owned under D3, while reusable templates remain global under D5. Add an explicit project owner for saved workflows, migrate existing rows to Personal, and keep example/templates as global copy sources. Shared/public workflow semantics need an explicit project rule. |
| Threads and messages | `nodetool_threads` has `workflow_id` only; `nodetool_messages.thread_id` only. A project row has one optional `thread_id`. | Thread/message models and `packages/websocket/src/trpc/routers/threads.ts`; web `GlobalChatStore`, chat hooks/components; mobile `ChatStore`, `ThreadsScreen`; project `ensureThread` creates one agent thread | `Thread.paginate` filters user and optional workflow, not project; message list is thread-scoped | Thread router deletes messages and thread; agent tools are read-only for thread deletion | Chats are project-owned and must support multiple threads. Add `project_id` to threads, migrate `projects.thread_id` to a project association without losing history, and require thread project context for message and tool operations. |
| Runs and background jobs | `jobs` is keyed by `workflow_id` and execution IDs; `run_events` and inbox rows key off `run_id`; no project column. Runtime run types and generation tracker carry optional project IDs. | Workflow runner, `packages/execution/src/service/workflow-run.ts`, session/cost ledger/generation tracker, websocket job routes, web `WorkflowRunsStore`/`LiveRunStore`, mobile Jobs screens | Jobs router and live WebSocket events; prediction ledger queries | Job cancellation removes/stops execution; run events/inbox are execution records and are not project-deleted by `Project.deleteOwned` | Project-owned execution context. Persist project ID at job/run creation, carry it through events and retries, and use it to route activity after a project switch. Deletion must wait for or cancel active runs and prevent retries from writing. |
| Predictions / generated outputs | `predictions.project_id` and `document_id` are nullable; `asset_ids` records generated asset IDs. Outputs are normally asset rows plus chat/message output refs. | `packages/execution/src/generation-tracker.ts`, cost ledger, provider generation paths, agent media and binary-output tools, chat turn | Prediction model/router/cost ledger and asset list; project summary only includes spend, not output resources | Prediction rows are history. Project delete currently leaves rows with the deleted project ID; assets are reassigned by the broad asset update | Project-owned when created by a project run or document. Migrate nullable legacy rows by thread/job/document where unambiguous, otherwise Personal. Keep output asset ownership and prediction ownership consistent; never leave a completed output pointing only at a deleted project. |
| Workspace files and folders | `nodetool_workspaces` stores user/path/default; files live behind runtime `Workspace` (local directory or cloud object prefix), not in project tables. | Web `useWorkspaces`, workspace components, tRPC `routers/workspace.ts`, REST download, agent `capabilities/files.ts`, CodeAct `workspace.*`, workflow workspace service, mobile app-runtime consumers | Workspace list/listFiles/readFile and agent `workspace.list`; local and cloud implementations share the runtime interface | Workspace row delete is blocked for default and linked workflows; file delete is available through workspace APIs | Project-owned files must be explicitly associated with a project or rooted in a project namespace. Preserve local/cloud parity through `Workspace.read/write/list/stat/copy/move/delete`; do not use `localDir` as the ownership mechanism. Migrate existing files to Personal or record an explicit mapping. |

## Global resources

These remain outside project ownership under D5: account settings and personal-data tables (`settings`, credentials, secrets, OAuth tokens), installed model/provider metadata, and reusable workflow/template examples. A template import creates a new project-owned workflow/document. Workspace rows are not global merely because they are user-owned today; their project-file role needs the boundary above.

## Cross-project references and move behavior

Q10 is unresolved in the current implementation. Document JSON and asset metadata can name assets, workflows, timelines, scripts, or entities without a database-level project foreign key. Existing rows therefore need a migration audit: retain assigned ownership, map unassigned references to Personal when the target is unambiguous, and mark ambiguous cross-project references for an explicit compatibility decision. Do not create a shared project as an accidental result.

Q11 is also unresolved. There is no generic document dependency copier in the inspected paths. `workspace.copy` copies files only, while `Project.assignDocument` moves one document/entity by changing `project_id`. A copy implementation must walk each supported document's references, deduplicate repeated asset/entity dependencies within one operation, rewrite internal IDs, and fail before committing when a dependency type cannot be copied.

Q13 has a concrete current entry point: `packages/models/src/project-membership.ts` and `packages/websocket/src/trpc/routers/projects.ts` allow moving storyboard, script, timeline, sketch, application, JavaScript script, and entity resources. The move changes ownership without updating references and does not check dependents. Future moves need either dependency-aware rewrites or a refusal with the affected references; a move must not silently break another project's document.

## Current gaps that are outside the project summary union

`ProjectDocumentType` covers storyboard, script, timeline, sketch, application, and JavaScript script. It does not cover workflows, folders/general assets, threads/messages, workspace files, jobs/runs, or generated output assets. `Project.deleteOwned` reassigns all seven membership tables, including all assets, to `default`, but does not archive, cancel active work, delete threads, remove workspace files, or reconcile prediction/output ownership. `Project` also has one `thread_id`, which cannot represent D9's multiple independent conversations.

Electron has workflow-only consumers and no project selector or project argument in its workflow fetch/tray paths. Mobile has an application project filter and project-shaped app documents, but its document backends and most screens still use `default` or unscoped lists. These clients must consume the same project-scoped API contracts as web rather than inventing separate ownership rules.
