diff --git a/.github/aw/github-agentic-workflows.md b/.github/aw/github-agentic-workflows.md index a9fb776a20c..340886078b0 100644 --- a/.github/aw/github-agentic-workflows.md +++ b/.github/aw/github-agentic-workflows.md @@ -548,43 +548,119 @@ The YAML frontmatter supports these fields: target-repo: "owner/repo" # Optional: cross-repository ``` Links issues as sub-issues using GitHub's parent-child relationships. Agent output includes `parent_issue_number` and `sub_issue_number`. Use with `create-issue` temporary IDs or existing issue numbers. - - `create-project:` - Create GitHub Projects V2 + - `create-project:` - Create a new GitHub Project board with optional fields and views ```yaml safe-outputs: create-project: max: 1 # Optional: max projects (default: 1) - github-token: ${{ secrets.PROJECTS_PAT }} # Optional: token with projects:write + # github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} # Optional: override default PAT (NOT GITHUB_TOKEN) target-owner: "org-or-user" # Optional: owner for created projects title-prefix: "[ai] " # Optional: prefix for project titles ``` + Use this to create new projects for organizing and tracking work across issues and pull requests. Can optionally specify custom fields, project views, and an initial item to add. + + **⚠️ IMPORTANT**: GitHub Projects requires a **Personal Access Token (PAT)** or GitHub App token with Projects permissions. The default `GITHUB_TOKEN` cannot be used. Ensure `${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}` exists and contains a token with: + - Classic PAT: `project` and `repo` scopes + - Fine-grained PAT: Organization permission `Projects: Read & Write` and repository access + + Project tools automatically fall back to `${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}` when per-output and top-level `github-token` values are omitted, so specifying `github-token` is optional unless you need to override the default token. Not supported for cross-repository operations. - - `update-project:` - Manage GitHub Projects boards + - `update-project:` - Add items to GitHub Projects, update custom fields, manage project structure ```yaml safe-outputs: update-project: max: 20 # Optional: max project operations (default: 10) - github-token: ${{ secrets.PROJECTS_PAT }} # Optional: token with projects:write + project: "https://github.com/orgs/myorg/projects/42" # REQUIRED in agent output (full URL) + # github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} # Optional here if GH_AW_PROJECT_GITHUB_TOKEN is set; PAT with projects:write (NOT GITHUB_TOKEN) is still required ``` - Agent output includes the `project` field as a **full GitHub project URL** (e.g., `https://github.com/orgs/myorg/projects/42` or `https://github.com/users/username/projects/5`). Project names or numbers alone are NOT accepted. + Use this to organize work by adding issues and pull requests to projects, updating field values (status, priority, effort, dates), creating custom fields, and setting up project views. + + **⚠️ IMPORTANT REQUIREMENTS:** + - Agent must include full project URL in **every** call: `project: "https://github.com/orgs/myorg/projects/42"` or `https://github.com/users/username/projects/5` + - Project URLs must be full URLs; project numbers alone are NOT accepted + - Requires a **PAT or GitHub App token** with Projects permissions (for example via `github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}` or the `GH_AW_PROJECT_GITHUB_TOKEN` fallback) + - Default `GITHUB_TOKEN` **cannot** access Projects v2 API + - Token scopes: + - Classic PAT: `project` and `repo` scopes + - Fine-grained PAT: Organization `Projects: Read & Write` permission + + **Three calling modes:** - For adding existing issues/PRs: Include `content_type` ("issue" or "pull_request") and `content_number`: + **Mode 1: Add/update existing issues or PRs** ```json - {"type": "update_project", "project": "https://github.com/orgs/myorg/projects/42", "content_type": "issue", "content_number": 123, "fields": {"Status": "In Progress"}} + { + "type": "update_project", + "project": "https://github.com/orgs/myorg/projects/42", + "content_type": "issue", + "content_number": 123, + "fields": {"Status": "In Progress", "Priority": "High"} + } ``` + - `content_type`: "issue" or "pull_request" + - `content_number`: The issue or PR number to add/update + - `fields`: Custom field values to set on the item (optional) - For creating draft issues: Include `content_type` as "draft_issue" with `draft_title` and optional `draft_body`: + **Mode 2: Create draft issues in the project** ```json - {"type": "update_project", "project": "https://github.com/orgs/myorg/projects/42", "content_type": "draft_issue", "draft_title": "Task title", "draft_body": "Task description", "fields": {"Status": "Todo"}} + { + "type": "update_project", + "project": "https://github.com/orgs/myorg/projects/42", + "content_type": "draft_issue", + "draft_title": "Follow-up: investigate performance", + "draft_body": "Check memory usage under load", + "temporary_id": "aw_abc123def456", + "fields": {"Status": "Backlog"} + } ``` + - `content_type`: "draft_issue" + - `draft_title`: Title of the draft issue (required when creating new) + - `draft_body`: Description in markdown (optional) + - `temporary_id`: Unique ID for this draft (format: `aw_` + 12 hex chars) for referencing in future updates (optional) + - `draft_issue_id`: Reference an existing draft by its temporary_id to update it (optional) + - `fields`: Custom field values (optional) + + **Mode 3: Create custom fields or views** (with `operation` field) + ```json + { + "type": "update_project", + "project": "https://github.com/orgs/myorg/projects/42", + "operation": "create_fields", + "field_definitions": [ + {"name": "Priority", "data_type": "SINGLE_SELECT", "options": ["High", "Medium", "Low"]}, + {"name": "Due Date", "data_type": "DATE"} + ] + } + ``` + - `operation`: "create_fields" or "create_view" + - `field_definitions`: Array of field definitions (for create_fields) + - `view`: View configuration object with `name`, `layout` (table/board/roadmap), optional `filter` and `visible_fields` (for create_view) Not supported for cross-repository operations. - - `create-project-status-update:` - Create GitHub project status updates + - `create-project-status-update:` - Post status updates to GitHub Projects for progress tracking ```yaml safe-outputs: create-project-status-update: - max: 10 # Optional: max status updates (default: 10) - github-token: ${{ secrets.PROJECTS_PAT }} # Optional: token with projects:write + max: 1 # Optional: max status updates (default: 1) + project: "https://github.com/orgs/myorg/projects/42" # REQUIRED in agent output (full URL) + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} # REQUIRED: PAT with projects:write (NOT GITHUB_TOKEN) ``` + Use this to provide stakeholders with regular updates on project status (on-track, at-risk, off-track, complete, inactive), timeline information, and progress summaries. Status updates create a historical record of project progress and enable tracking over time. + + **⚠️ IMPORTANT REQUIREMENTS:** + - Agent must include full project URL in **every** call: `project: "https://github.com/orgs/myorg/projects/42"` + - Requires a **PAT or GitHub App token** with Projects permissions configured as `github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}` + - Default `GITHUB_TOKEN` **cannot** access Projects v2 API + - Token scopes: + - Classic PAT: `project` and `repo` scopes + - Fine-grained PAT: Organization `Projects: Read & Write` permission + + **Agent output fields:** + - `project`: Full project URL (required) - MUST be explicitly included in output + - `status`: ON_TRACK, AT_RISK, OFF_TRACK, COMPLETE, or INACTIVE (optional, defaults to ON_TRACK) + - `start_date`: Project start date in YYYY-MM-DD format (optional) + - `target_date`: Project end date in YYYY-MM-DD format (optional) + - `body`: Status summary in markdown (required) + Not supported for cross-repository operations. - `push-to-pull-request-branch:` - Push changes to PR branch ```yaml diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 47a9f5097f9..1f74896bac9 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -414,7 +414,7 @@ jobs: "name": "noop" }, { - "description": "Add or update items in GitHub Projects v2 boards. Can add issues/PRs to a project and update custom field values. Requires the project URL, content type (issue or pull_request), and content number.\n\nThree usage modes:\n1. Add/update project item: Requires project + content_type. For 'issue' or 'pull_request', also requires content_number. For 'draft_issue', requires draft_title.\n2. Create project fields: Requires project + operation='create_fields' + field_definitions.\n3. Create project view: Requires project + operation='create_view' + view.", + "description": "Manage GitHub Projects: add issues/pull requests/draft issues, update item fields (status, priority, effort, dates), manage custom fields, and create project views. Use this to organize work by adding items to projects, updating field values, creating custom fields up-front, and setting up project views (table, board, roadmap).\n\nThree modes: (1) Add or update project items with custom field values; (2) Create project fields; (3) Create project views. This is the primary tool for ProjectOps automation - add items to projects, set custom fields for tracking, and organize project boards.", "inputSchema": { "additionalProperties": false, "properties": { @@ -492,8 +492,8 @@ jobs: "type": "string" }, "project": { - "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'). Project names or numbers alone are NOT accepted.", - "pattern": "^https://github\\.com/(orgs|users)/[^/]+/projects/\\d+$", + "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc123def456' or 'aw_abc123def456'). Project names or numbers alone are NOT accepted.", + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[0-9a-f]{12})$", "type": "string" }, "view": { @@ -564,7 +564,7 @@ jobs: "name": "missing_data" }, { - "description": "Create a status update on a GitHub Projects v2 board to communicate project progress. Use this when you need to provide stakeholder updates with status indicators, timeline information, and progress summaries. Status updates create a historical record of project progress tracked over time. Requires project URL, status indicator, dates, and markdown body describing progress/trends/findings.", + "description": "Post a status update to a GitHub Project to communicate progress and health. Use this to provide stakeholders with regular updates on project status (on-track, at-risk, off-track, complete, inactive), timeline information, and progress summaries. Status updates create a historical record of project progress, enabling tracking over time and informed decision-making.", "inputSchema": { "additionalProperties": false, "properties": { diff --git a/.github/workflows/test-project-url-default.lock.yml b/.github/workflows/test-project-url-default.lock.yml index a784d079808..080de7534f8 100644 --- a/.github/workflows/test-project-url-default.lock.yml +++ b/.github/workflows/test-project-url-default.lock.yml @@ -250,7 +250,7 @@ jobs: "name": "noop" }, { - "description": "Add or update items in GitHub Projects v2 boards. Can add issues/PRs to a project and update custom field values. Requires the project URL, content type (issue or pull_request), and content number.\n\nThree usage modes:\n1. Add/update project item: Requires project + content_type. For 'issue' or 'pull_request', also requires content_number. For 'draft_issue', requires draft_title.\n2. Create project fields: Requires project + operation='create_fields' + field_definitions.\n3. Create project view: Requires project + operation='create_view' + view.", + "description": "Manage GitHub Projects: add issues/pull requests/draft issues, update item fields (status, priority, effort, dates), manage custom fields, and create project views. Use this to organize work by adding items to projects, updating field values, creating custom fields up-front, and setting up project views (table, board, roadmap).\n\nThree modes: (1) Add or update project items with custom field values; (2) Create project fields; (3) Create project views. This is the primary tool for ProjectOps automation - add items to projects, set custom fields for tracking, and organize project boards.", "inputSchema": { "additionalProperties": false, "properties": { @@ -328,8 +328,8 @@ jobs: "type": "string" }, "project": { - "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'). Project names or numbers alone are NOT accepted.", - "pattern": "^https://github\\.com/(orgs|users)/[^/]+/projects/\\d+$", + "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc123def456' or 'aw_abc123def456'). Project names or numbers alone are NOT accepted.", + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[0-9a-f]{12})$", "type": "string" }, "view": { @@ -400,7 +400,7 @@ jobs: "name": "missing_data" }, { - "description": "Create a status update on a GitHub Projects v2 board to communicate project progress. Use this when you need to provide stakeholder updates with status indicators, timeline information, and progress summaries. Status updates create a historical record of project progress tracked over time. Requires project URL, status indicator, dates, and markdown body describing progress/trends/findings.", + "description": "Post a status update to a GitHub Project to communicate progress and health. Use this to provide stakeholders with regular updates on project status (on-track, at-risk, off-track, complete, inactive), timeline information, and progress summaries. Status updates create a historical record of project progress, enabling tracking over time and informed decision-making.", "inputSchema": { "additionalProperties": false, "properties": { diff --git a/actions/setup/js/safe_outputs_tools.json b/actions/setup/js/safe_outputs_tools.json index 42fe8b80b2d..f05c0ecbbcc 100644 --- a/actions/setup/js/safe_outputs_tools.json +++ b/actions/setup/js/safe_outputs_tools.json @@ -600,7 +600,7 @@ }, { "name": "update_project", - "description": "Add or update items in GitHub Projects v2 boards. Can add issues/PRs to a project and update custom field values. Requires the project URL, content type (issue or pull_request), and content number.\n\nThree usage modes:\n1. Add/update project item: Requires project + content_type. For 'issue' or 'pull_request', also requires content_number. For 'draft_issue', requires draft_title.\n2. Create project fields: Requires project + operation='create_fields' + field_definitions.\n3. Create project view: Requires project + operation='create_view' + view.", + "description": "Manage GitHub Projects: add issues/pull requests/draft issues, update item fields (status, priority, effort, dates), manage custom fields, and create project views. Use this to organize work by adding items to projects, updating field values, creating custom fields up-front, and setting up project views (table, board, roadmap).\n\nThree modes: (1) Add or update project items with custom field values; (2) Create project fields; (3) Create project views. This is the primary tool for ProjectOps automation - add items to projects, set custom fields for tracking, and organize project boards.", "inputSchema": { "type": "object", "required": ["project"], @@ -735,7 +735,7 @@ }, { "name": "create_project", - "description": "Create a new empty GitHub Projects v2 board. Use this to create a project board for organizing work. The project is created empty and can be populated with issues and custom fields after creation. Returns a temporary project ID that can be used in subsequent update_project calls before the actual project URL is available.", + "description": "Create a new GitHub Project for organizing and tracking work across issues and pull requests. You can optionally provide a title, owner, owner_type, and an initial issue item_url to add to the project. You may also provide a temporary_id to reference this project before it is created; if not provided, a temporary_id will be auto-generated and returned, and can be used in subsequent update_project calls via the '#aw_ID' syntax.", "inputSchema": { "type": "object", "required": [], @@ -769,7 +769,7 @@ }, { "name": "create_project_status_update", - "description": "Create a status update on a GitHub Projects v2 board to communicate project progress. Use this when you need to provide stakeholder updates with status indicators, timeline information, and progress summaries. Status updates create a historical record of project progress tracked over time. Requires project URL, status indicator, dates, and markdown body describing progress/trends/findings.", + "description": "Post a status update to a GitHub Project to communicate progress and health. Use this to provide stakeholders with regular updates on project status (on-track, at-risk, off-track, complete, inactive), timeline information, and progress summaries. Status updates create a historical record of project progress, enabling tracking over time and informed decision-making.", "inputSchema": { "type": "object", "required": ["project", "body"], diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index ad53b9bace3..822e2aa3103 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -4061,7 +4061,7 @@ "oneOf": [ { "type": "object", - "description": "Configuration for managing GitHub Projects v2 boards. Smart tool that can add issue/PR items and update custom fields on existing items. By default it is update-only: if the project does not exist, the job fails with instructions to create it manually. To allow workflows to create missing projects, explicitly opt in via the agent output field create_if_missing=true (and/or provide a github-token override). NOTE: Projects v2 requires a Personal Access Token (PAT) or GitHub App token with appropriate permissions; the GITHUB_TOKEN cannot be used for Projects v2. Safe output items produced by the agent use type=update_project. Configuration also supports an optional views array for declaring project views to create. Safe output items produced by the agent use type=update_project and may include: project (board name), content_type (issue|pull_request), content_number, fields, and create_if_missing.", + "description": "Configuration for managing GitHub Projects boards. Enable agents to add issues and pull requests to projects, update custom field values (status, priority, effort, dates), create project fields and views. By default it is update-only: if the project does not exist, the job fails with instructions to create it. To allow workflows to create missing projects, explicitly opt in via agent output field create_if_missing=true. Requires a Personal Access Token (PAT) or GitHub App token with Projects permissions (default GITHUB_TOKEN cannot be used). Agent output includes: project (full URL or temporary project ID like aw_XXXXXXXXXXXX or #aw_XXXXXXXXXXXX from create_project), content_type (issue|pull_request|draft_issue), content_number, fields, create_if_missing. For specialized operations, agent can also provide: operation (create_fields|create_view), field_definitions (array of field configs when operation=create_fields), view (view config object when operation=create_view).", "required": ["project"], "properties": { "max": { @@ -4160,13 +4160,13 @@ "description": "Enable project management with default configuration (max=10)" } ], - "description": "Enable AI agents to update GitHub Project items (issues, pull requests) with status changes, field updates, and metadata modifications." + "description": "Enable AI agents to add items to GitHub Projects, update custom fields, and manage project structure. Use this for organizing work into projects with status tracking, priority management, and custom metadata." }, "create-project": { "oneOf": [ { "type": "object", - "description": "Configuration for creating new GitHub Projects v2 boards. Creates a new empty project that can be populated with issues and custom fields. Requires a Personal Access Token (PAT) or GitHub App token with Projects permissions; the GITHUB_TOKEN cannot be used. Safe output items use type=create_project and include: title (project name), owner (org/user login), owner_type ('org' or 'user', default: 'org'), and optional item_url (GitHub issue URL to add as first item). The target-owner can be configured in the workflow frontmatter to provide a default that the agent can use or override.", + "description": "Configuration for creating new GitHub Projects boards. Enables agents to create new project boards with optional custom fields, views, and an initial item. Requires a Personal Access Token (PAT) or GitHub App token with Projects write permission (default GITHUB_TOKEN cannot be used). Agent output includes: title (project name), owner (org/user login, uses default if omitted), owner_type ('org' or 'user'), optional item_url (issue to add as first item), and optional field_definitions. Returns a temporary project ID for use in subsequent update_project operations.", "properties": { "max": { "type": "integer", @@ -4264,13 +4264,13 @@ "default": { "max": 1 }, - "description": "Enable AI agents to create new GitHub Project boards with custom fields, views, and configurations." + "description": "Enable AI agents to create new GitHub Projects for organizing and tracking work across issues and pull requests." }, "create-project-status-update": { "oneOf": [ { "type": "object", - "description": "Configuration for creating GitHub Project status updates. Status updates provide stakeholder communication and historical record of project progress. Requires a Personal Access Token (PAT) or GitHub App token with Projects: Read+Write permission. The GITHUB_TOKEN cannot be used for Projects v2. Status updates are created on the specified project board and appear in the Updates tab. Typically used by orchestrators to post run summaries with progress, findings, and next steps.", + "description": "Configuration for posting status updates to GitHub Projects. Status updates provide stakeholder communication about project progress, health, and timeline. Each update appears in the project's Updates tab and creates a historical record. Requires a Personal Access Token (PAT) or GitHub App token with Projects read & write permission (default GITHUB_TOKEN cannot be used). Typically used by scheduled workflows or orchestrators to post regular progress summaries with status indicators (on-track, at-risk, off-track, complete, inactive), dates, and progress details.", "required": ["project"], "properties": { "max": { @@ -4306,7 +4306,7 @@ "description": "Enable project status updates with default configuration (max=1)" } ], - "description": "Enable AI agents to post status updates to GitHub Projects, providing progress reports and milestone tracking." + "description": "Enable AI agents to post status updates to GitHub Projects for progress tracking and stakeholder communication." }, "create-discussion": { "oneOf": [ diff --git a/pkg/workflow/js/safe_outputs_tools.json b/pkg/workflow/js/safe_outputs_tools.json index a7a85800d7d..b8663fe8d27 100644 --- a/pkg/workflow/js/safe_outputs_tools.json +++ b/pkg/workflow/js/safe_outputs_tools.json @@ -774,7 +774,7 @@ }, { "name": "update_project", - "description": "Add or update items in GitHub Projects v2 boards. Can add issues/PRs to a project and update custom field values. Requires the project URL, content type (issue or pull_request), and content number.\n\nThree usage modes:\n1. Add/update project item: Requires project + content_type. For 'issue' or 'pull_request', also requires content_number. For 'draft_issue', requires draft_title.\n2. Create project fields: Requires project + operation='create_fields' + field_definitions.\n3. Create project view: Requires project + operation='create_view' + view.", + "description": "Manage GitHub Projects: add issues/pull requests/draft issues, update item fields (status, priority, effort, dates), manage custom fields, and create project views. Use this to organize work by adding items to projects, updating field values, creating custom fields up-front, and setting up project views (table, board, roadmap).\n\nThree modes: (1) Add or update project items with custom field values; (2) Create project fields; (3) Create project views. This is the primary tool for ProjectOps automation - add items to projects, set custom fields for tracking, and organize project boards.", "inputSchema": { "type": "object", "required": [ @@ -783,8 +783,8 @@ "properties": { "project": { "type": "string", - "pattern": "^https://github\\.com/(orgs|users)/[^/]+/projects/\\d+$", - "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'). Project names or numbers alone are NOT accepted." + "pattern": "^(https://github\\.com/(orgs|users)/[^/]+/projects/\\d+|#?aw_[0-9a-f]{12})$", + "description": "Full GitHub project URL (e.g., 'https://github.com/orgs/myorg/projects/42' or 'https://github.com/users/username/projects/5'), or a temporary project ID from a recent create_project call (e.g., '#aw_abc123def456' or 'aw_abc123def456'). Project names or numbers alone are NOT accepted." }, "operation": { "type": "string", @@ -924,7 +924,7 @@ }, { "name": "create_project", - "description": "Create a new empty GitHub Projects v2 board. Use this to create a project board for organizing work. The project is created empty and can be populated with issues and custom fields after creation.", + "description": "Create a new GitHub Project board. Use this to create a new project for organizing and tracking work across issues and pull requests, owned by a specific user or organization. You can optionally provide a custom title and add an initial issue item to the project via item_url.", "inputSchema": { "type": "object", "required": [], @@ -949,6 +949,11 @@ "type": "string", "pattern": "^https://github\\\\.com/[^/]+/[^/]+/issues/\\\\d+$", "description": "Optional GitHub issue URL to add as the first item to the project (e.g., 'https://github.com/owner/repo/issues/123')." + }, + "temporary_id": { + "type": "string", + "pattern": "^aw_[0-9a-f]{12}$", + "description": "Optional temporary identifier for referencing this project before it's created. Format: 'aw_' followed by 12 hex characters (e.g., 'aw_abc123def456'). If not provided, one will be auto-generated and returned in the response. Use '#aw_ID' in update_project to reference this project by its temporary_id." } }, "additionalProperties": false @@ -956,7 +961,7 @@ }, { "name": "create_project_status_update", - "description": "Create a status update on a GitHub Projects v2 board to communicate project progress. Use this when you need to provide stakeholder updates with status indicators, timeline information, and progress summaries. Status updates create a historical record of project progress tracked over time. Requires project URL, status indicator, dates, and markdown body describing progress/trends/findings.", + "description": "Post a status update to a GitHub Project to communicate progress and health. Use this to provide stakeholders with regular updates on project status (on-track, at-risk, off-track, complete, inactive), timeline information, and progress summaries. Status updates create a historical record of project progress, enabling tracking over time and informed decision-making.", "inputSchema": { "type": "object", "required": [