feat: extends the tm context command to accept a brief ID directly or…#1219
feat: extends the tm context command to accept a brief ID directly or…#1219Crunchyman-ralph merged 3 commits intonextfrom
Conversation
|
WalkthroughAdds an optional positional Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant CLI as CLI
participant C as ContextCommand
participant B as Brief API
participant O as Org API
participant S as Context Store
U->>CLI: context [briefOrUrl]
CLI->>C: run(briefOrUrl)
C->>C: extractBriefId(input)
alt briefId found
C->>B: getBrief(briefId)
B-->>C: brief (contains orgId?)
opt orgId present
C->>O: getOrg(orgId)
O-->>C: org (optional)
end
C->>S: set({ orgId, orgName?, briefId, briefName })
C-->>CLI: success / display result
else no briefId
C-->>CLI: error / guidance
end
sequenceDiagram
autonumber
participant U as User
participant CLI as CLI
participant C as ContextCommand
participant S as Context Store
U->>CLI: context
CLI->>C: run()
C->>S: getCurrent()
S-->>C: { org?, brief? }
C-->>CLI: display current context
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (1)
apps/cli/src/commands/context.command.ts(2 hunks)
🔇 Additional comments (3)
apps/cli/src/commands/context.command.ts (3)
52-54: Nice DX: positional arg for brief/URL.Good, backward‑compatible way to fast‑path the common case.
Please quickly sanity‑check that subcommands still take precedence in Commander:
- tm context org
- tm context brief
- tm context set --org 123
- tm context https://tux.tryhamster.com/home/hamster/briefs/
55-61: Default action flow reads well.Early return into the new resolver keeps the default “show context” behavior intact when no arg is provided.
451-516: Happy path LGTM; spinner + context update are consistent with existing commands.Flow mirrors the other executors (auth check, spinner, updateContext, lastResult). Good UX touches with org name fallback.
… a hamster brief URL from which to use the brief and sets the organization and brief automatically
5b15336 to
ae0c52b
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
apps/cli/src/commands/context.command.ts (3)
468-471: Avoid hard‑coding the host in the error hint.Make the hint environment‑agnostic (placeholder or derive from config).
Apply:
- ui.displayError( - 'Provide a valid brief ID or a Hamster brief URL, e.g. https://tux.tryhamster.com/home/hamster/briefs/<id>' - ); + ui.displayError( + 'Provide a valid brief ID or a Hamster brief URL, e.g. https://<host>/.../briefs/<id>' + );
550-556: Broaden ID heuristic to cover ULIDs and general sluggy tokens.Prevents false negatives when users paste non‑UUID IDs.
Apply:
private isLikelyId(value: string): boolean { - // Accept standard UUIDs or reasonably long hex-with-dashes IDs - const uuidRegex = - /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; - const looseRegex = /^[0-9a-fA-F-]{16,}$/; - return uuidRegex.test(value) || looseRegex.test(value); + const uuidRegex = + /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; + const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i; // ULID + const slugRegex = /^[A-Za-z0-9_-]{16,}$/; // general long token + return uuidRegex.test(value) || ulidRegex.test(value) || slugRegex.test(value); }
521-545: Relax brief ID extraction: accept scheme‑less URLs, query params, and path tokens; let the API be the validator.Current logic rejects common inputs (e.g., tux.tryhamster.com/... or ULIDs).
Apply:
- private extractBriefId(input: string): string | null { - // If it's a URL, try to parse and take the last path segment - try { - const url = new URL(input); - const parts = url.pathname.split('/').filter(Boolean); - // Look for a path segment after 'briefs', otherwise fallback to last segment - const briefsIndex = parts.lastIndexOf('briefs'); - let candidate = - briefsIndex >= 0 && parts.length > briefsIndex + 1 - ? parts[briefsIndex + 1] - : parts[parts.length - 1]; - candidate = candidate?.trim(); - if (candidate && this.isLikelyId(candidate)) { - return candidate; - } - } catch { - // Not a URL, fall through and treat as raw ID - } - - // Treat as raw ID - if (input && this.isLikelyId(input)) { - return input; - } - return null; - } + private extractBriefId(input: string): string | null { + const raw = input?.trim() ?? ''; + if (!raw) return null; + + const parseUrl = (s: string): URL | null => { + try { return new URL(s); } catch {} + try { return new URL(`https://${s}`); } catch {} + return null; + }; + + const fromParts = (path: string): string | null => { + const parts = path.split('/').filter(Boolean); + const briefsIdx = parts.lastIndexOf('briefs'); + const candidate = + briefsIdx >= 0 && parts.length > briefsIdx + 1 + ? parts[briefsIdx + 1] + : parts[parts.length - 1]; + return candidate?.trim() || null; + }; + + // 1) URL (absolute or scheme‑less) + const url = parseUrl(raw); + if (url) { + const qId = url.searchParams.get('id') || url.searchParams.get('briefId'); + const candidate = (qId || fromParts(url.pathname)) ?? null; + if (candidate && (this.isLikelyId(candidate) || candidate.length >= 8)) { + return candidate; + } + } + + // 2) Path‑like input without scheme + if (raw.includes('/')) { + const candidate = fromParts(raw); + if (candidate && (this.isLikelyId(candidate) || candidate.length >= 8)) { + return candidate; + } + } + + // 3) Fallback: raw token (API will validate) + return raw; + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (1)
apps/cli/src/commands/context.command.ts(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (1)
apps/cli/src/commands/context.command.ts (1)
52-62: Nice addition: optional positional arg + default action wiring looks good.Backwards compatible with existing subcommands; help text is clear.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/cli/src/commands/context.command.ts (1)
454-518: Spinner scope bug + exit path: spinner may keep spinning on errors; also guard example host when env is unset.
spinneris declared insidetrybut referenced incatch; if an error occurs, it may not stop. Also, the error hint can print “https://undefined/...”.Apply:
- private async executeSetFromBriefInput(briefOrUrl: string): Promise<void> { - try { + private async executeSetFromBriefInput(briefOrUrl: string): Promise<void> { + let spinner: ReturnType<typeof ora> | undefined; + try { // Check authentication if (!this.authManager.isAuthenticated()) { ui.displayError('Not authenticated. Run "tm auth login" first.'); process.exit(1); } - let spinner = ora('Resolving brief...'); - spinner.start(); + spinner = ora('Resolving brief...').start(); // Extract brief ID const briefId = this.extractBriefId(briefOrUrl); if (!briefId) { spinner.fail('Could not extract a brief ID from the provided input'); - ui.displayError( - `Provide a valid brief ID or a Hamster brief URL, e.g. https://${process.env.TM_PUBLIC_BASE_DOMAIN}/home/hamster/briefs/<id>` - ); + const exampleHost = process.env.TM_PUBLIC_BASE_DOMAIN || '<host>'; + ui.displayError( + `Provide a valid brief ID or a Hamster brief URL, e.g. https://${exampleHost}/home/hamster/briefs/<id>` + ); process.exit(1); } @@ - } catch (error: any) { - try { if (spinner?.isSpinning) spinner.stop(); } catch {} + } catch (error: any) { + try { if (spinner?.isSpinning) spinner.stop(); } catch {} this.handleError(error); process.exit(1); } }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
.changeset/pre.json(0 hunks).changeset/shiny-regions-teach.md(1 hunks)apps/cli/src/commands/context.command.ts(2 hunks)package.json(1 hunks)
💤 Files with no reviewable changes (1)
- .changeset/pre.json
🧰 Additional context used
📓 Path-based instructions (3)
package.json
📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)
Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci
Files:
package.json
.changeset/*.md
📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)
.changeset/*.md: When runningnpm run changesetornpx changeset add, provide a concise summary of the changes for theCHANGELOG.mdin imperative mood, typically a single line, and not a detailed Git commit message.
The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Do not use your detailed Git commit message body as the changeset summary.
Files:
.changeset/shiny-regions-teach.md
.changeset/*
📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)
Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Files:
.changeset/shiny-regions-teach.md
🧠 Learnings (10)
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: For CLI usage, install Taskmaster globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.
Applied to files:
package.json.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to .changeset/* : Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-18T17:19:27.365Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/.windsurfrules:0-0
Timestamp: 2025-07-18T17:19:27.365Z
Learning: Use `task-master add-task` to add a new task to tasks.json using AI.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-18T17:19:27.365Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/.windsurfrules:0-0
Timestamp: 2025-07-18T17:19:27.365Z
Learning: Use the global `task-master` CLI command instead of directly invoking `node scripts/dev.js` for all task management operations.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-09-03T12:15:03.208Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: apps/cli/src/commands/auth.command.ts:222-224
Timestamp: 2025-09-03T12:15:03.208Z
Learning: The CLI can be invoked using both "task-master" and "tm" as aliases - both forms are valid and acceptable in help text, documentation, and examples.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Use the Taskmaster command set (`task-master` CLI or MCP tools) for all task management operations: listing, expanding, updating, tagging, and status changes.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for integrating new features into the Task Master CLI with tagged system considerations (new_features.mdc).
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : Implement version checking to notify users of available updates, use non-blocking version checks, and display update notifications after command completion.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : Integrate version checking in the CLI run function, starting the update check in the background and displaying notifications after command execution.
Applied to files:
.changeset/shiny-regions-teach.md
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : For AI-powered commands that benefit from project context, use the ContextGatherer utility for multi-source context extraction, support task IDs, file paths, custom context, and project tree, implement fuzzy search for automatic task discovery, and display detailed token breakdown for transparency.
Applied to files:
apps/cli/src/commands/context.command.ts
🧬 Code graph analysis (1)
apps/cli/src/commands/context.command.ts (1)
tests/unit/ui.test.js (1)
chalk(17-17)
🪛 GitHub Actions: CI
apps/cli/src/commands/context.command.ts
[error] 512-585: Biome format check failed. Formatting issues detected by the Biome formatter; the content would be reformatted. Run 'npm run format-check' to fix.
🔇 Additional comments (3)
package.json (1)
3-3: Pre-release flow correct — no version regressionpackage.json: 0.27.0-rc.1; .changeset/pre.json: mode="pre", tag="rc", initialVersions.task-master-ai="0.26.0". Bump 0.26.0 → 0.27.0-rc.1 matches the pre-release flow; the reported regression from 1.0.0-rc.2 → 0.27.0-rc.1 is incorrect. No action required.
apps/cli/src/commands/context.command.ts (2)
520-575: Formatting/lint and small robustness tweaks in extractBriefId (format aborted — Biome config error)File: apps/cli/src/commands/context.command.ts (extractBriefId). Running
npm run formatfailed: Biome errored on unknown keys ("ignore", "include") in biome.json — fix the config or run the formatter locally and re-run CI.- const parseUrl = (s: string): URL | null => { - try { return new URL(s); } catch {} - try { return new URL(`https://${s}`); } catch {} - return null; - }; + const parseUrl = (s: string): URL | null => { + try { + return new URL(s); + } catch { + /* ignore */ + } + try { + return new URL(`https://${s}`); + } catch { + /* ignore */ + } + return null; + }; @@ - const qId = url.searchParams.get('id') || url.searchParams.get('briefId'); + const qId = + url.searchParams.get('id') || + url.searchParams.get('briefId') || + url.searchParams.get('brief');
52-61: Docs: document the new optional [briefOrUrl] positional in CLI help/examples and READMEThe command adds this.argument('[briefOrUrl]', 'Brief ID or Hamster brief URL') at apps/cli/src/commands/context.command.ts:52–56 — update docs/command-reference.md and README-task-master.md with usage examples like:
- tm context
- tm context https://<TM_PUBLIC_BASE_DOMAIN>/home/hamster/briefs/
| "task-master-ai": minor | ||
| --- | ||
|
|
||
| @tm/cli: add auto-update functionality to every command |
There was a problem hiding this comment.
Changeset summary doesn’t match this PR; make it user-facing and about tm context brief/URL support.
Use a concise, imperative, user-facing line describing the new behavior.
Apply:
-@tm/cli: add auto-update functionality to every command
+Add support for passing a brief ID or Hamster brief URL to `tm context` to auto-set organization and brief📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @tm/cli: add auto-update functionality to every command | |
| Add support for passing a brief ID or Hamster brief URL to `tm context` to auto-set organization and brief |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
.changeset/shiny-regions-teach.md around line 5: the changeset summary is not
user-facing and doesn't match the PR; replace the current terse note "@tm/cli:
add auto-update functionality to every command" with a concise, imperative,
user-facing summary that matches the PR scope — e.g. "tm: add brief/URL support
for context and enable auto-update for commands" (or adjust wording to exactly
reflect the PR), keeping it a single line and imperative.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/cli/src/commands/context.command.ts (1)
466-475: Avoid “https://undefined/…” in error hint; add a safe fallback host.If
TM_PUBLIC_BASE_DOMAINisn’t set, the hint printsundefined. Use a placeholder fallback.Apply:
- ui.displayError( - `Provide a valid brief ID or a Hamster brief URL, e.g. https://${process.env.TM_PUBLIC_BASE_DOMAIN}/home/hamster/briefs/<id>` - ); + const host = process.env.TM_PUBLIC_BASE_DOMAIN || '<host>'; + ui.displayError( + `Provide a valid brief ID or a Hamster brief URL, e.g. https://${host}/.../briefs/<id>` + );
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
apps/cli/src/commands/context.command.ts(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test
🔇 Additional comments (3)
apps/cli/src/commands/context.command.ts (3)
9-9: Typed ora import is correct.Using
ora, { Ora }keeps the spinner typed and avoidsany.
52-61: Confirm subcommand precedence with new positional arg.Commander should prefer subcommands over the root action, but please verify:
tm context orgstill invokes the org flow, notexecuteSetFromBriefInput('org').tm context set --org ...still routes to thesetsubcommand.
577-585: ID heuristic looks good.Covers UUID, ULID, and long slug tokens; balanced without over‑restricting.
| private extractBriefId(input: string): string | null { | ||
| const raw = input?.trim() ?? ''; | ||
| if (!raw) return null; | ||
|
|
||
| const parseUrl = (s: string): URL | null => { | ||
| try { | ||
| return new URL(s); | ||
| } catch {} | ||
| try { | ||
| return new URL(`https://${s}`); | ||
| } catch {} | ||
| return null; | ||
| }; | ||
|
|
||
| const fromParts = (path: string): string | null => { | ||
| const parts = path.split('/').filter(Boolean); | ||
| const briefsIdx = parts.lastIndexOf('briefs'); | ||
| const candidate = | ||
| briefsIdx >= 0 && parts.length > briefsIdx + 1 | ||
| ? parts[briefsIdx + 1] | ||
| : parts[parts.length - 1]; | ||
| return candidate?.trim() || null; | ||
| }; | ||
|
|
||
| // 1) URL (absolute or scheme‑less) | ||
| const url = parseUrl(raw); | ||
| if (url) { | ||
| const qId = url.searchParams.get('id') || url.searchParams.get('briefId'); | ||
| const candidate = (qId || fromParts(url.pathname)) ?? null; | ||
| if (candidate) { | ||
| // Light sanity check; let API be the final validator | ||
| if (this.isLikelyId(candidate) || candidate.length >= 8) | ||
| return candidate; | ||
| } | ||
| } | ||
|
|
||
| // 2) Looks like a path without scheme | ||
| if (raw.includes('/')) { | ||
| const candidate = fromParts(raw); | ||
| if (candidate && (this.isLikelyId(candidate) || candidate.length >= 8)) { | ||
| return candidate; | ||
| } | ||
| } | ||
|
|
||
| // 3) Fallback: raw token | ||
| return raw; | ||
| } |
There was a problem hiding this comment.
❓ Verification inconclusive
Don’t return the entire URL as an ID; percent‑decode extracted segments.
When no ID is found in a URL/path, extractBriefId falls back to returning the raw input, which can pass a full URL to getBrief(...) and produce misleading “not found” errors. Also, handle percent‑encoded path segments.
Apply:
private extractBriefId(input: string): string | null {
const raw = input?.trim() ?? '';
if (!raw) return null;
const parseUrl = (s: string): URL | null => {
try {
return new URL(s);
} catch {}
try {
return new URL(`https://${s}`);
} catch {}
return null;
};
+ const safeDecode = (s: string): string => {
+ try {
+ return decodeURIComponent(s);
+ } catch {
+ return s;
+ }
+ };
+
const fromParts = (path: string): string | null => {
const parts = path.split('/').filter(Boolean);
const briefsIdx = parts.lastIndexOf('briefs');
const candidate =
briefsIdx >= 0 && parts.length > briefsIdx + 1
? parts[briefsIdx + 1]
: parts[parts.length - 1];
- return candidate?.trim() || null;
+ const trimmed = candidate?.trim();
+ return trimmed ? safeDecode(trimmed) : null;
};
// 1) URL (absolute or scheme‑less)
const url = parseUrl(raw);
if (url) {
- const qId = url.searchParams.get('id') || url.searchParams.get('briefId');
- const candidate = (qId || fromParts(url.pathname)) ?? null;
+ const qId = url.searchParams.get('id') || url.searchParams.get('briefId');
+ const rawCandidate = qId || fromParts(url.pathname);
+ const candidate = rawCandidate ? safeDecode(rawCandidate) : null;
if (candidate) {
// Light sanity check; let API be the final validator
if (this.isLikelyId(candidate) || candidate.length >= 8)
return candidate;
}
}
// 2) Looks like a path without scheme
if (raw.includes('/')) {
const candidate = fromParts(raw);
if (candidate && (this.isLikelyId(candidate) || candidate.length >= 8)) {
return candidate;
}
- }
+ // Looked like a path but no plausible ID
+ return null;
+ }
// 3) Fallback: raw token
- return raw;
+ return raw;
}Follow‑ups:
- Consider also accepting
briefas a query key if that’s used elsewhere.
Don't return the entire URL as the brief ID; percent‑decode extracted segments and return null when no plausible ID exists.
File: apps/cli/src/commands/context.command.ts — extractBriefId (lines 526–572)
extractBriefId can pass a full URL/domain to getBrief(...) when parsing fails. Add a safe decode (decodeURIComponent with try/catch) and apply it to query/path segments (qId and fromParts), decode before validation, and if raw.includes('/') but no plausible id was found, return null instead of falling back to the raw input.
- Add safeDecode(s) and apply to qId and fromParts result.
- Decode candidate before calling isLikelyId / length checks.
- In the raw.includes('/') branch, return null when candidate isn't plausible (prevent returning a URL/domain).
- Optional: accept query key 'brief' as well.
🤖 Prompt for AI Agents
In apps/cli/src/commands/context.command.ts around lines 526–572, extractBriefId
currently may return the full URL/domain and doesn't percent‑decode segments;
add a small helper safeDecode(s: string): string | null that uses try { return
decodeURIComponent(s) } catch { return null }, use it to decode the query values
(check url.searchParams for 'id', 'briefId', and 'brief') and the value returned
from fromParts before any validation, then run isLikelyId/length checks against
the decoded candidate; also change the raw.includes('/') branch so that if a
candidate exists but is not plausible you return null (do not fall back to
returning the raw input), leaving the final fallback to return raw only when no
slash was present and no decoding/parsing applied.
This PR was automatically generated to update documentation based on recent changes. Original commit: feat: extends the tm context command to accept a brief ID directly or… (#1219)\n\nCo-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>\n\n Co-authored-by: Claude <claude-assistant@anthropic.com>
eyaltoledano#1219) Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
extends the tm context command to accept a brief ID directly or a hamster brief URL from which to use the brief and sets the organization and brief automatically
Summary by CodeRabbit
New Features
Improvements
Chores