apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

apply claude code fixes - #37

Merged
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff
Feb 18, 2026
Merged

apply claude code fixes#37
andmoredev merged 5 commits into
mainfrom
try-to-fix-some-stuff

Conversation

@andmoredev

Copy link
Copy Markdown
Contributor

No description provided.

CopilotAI review requested due to automatic review settings February 18, 2026 19:10

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request applies Claude code fixes to improve timestamp handling and transcript extraction. The changes add millisecond support to time parsing functions and implement SRT-based transcript extraction for clip retrieval with fallback to AI-stored text.

Changes:

  • Added millisecond support to timeToSeconds functions in video-processing.mjs and transcripts.mjs to handle formats like HH:MM:SS,mmm
  • Implemented SRT file loading and time-range-based transcript extraction in get-clip.mjs with fallback to stored segment text
  • Updated AI agent prompt examples to show millisecond timestamps and improved JSON formatting
  • Added simplified architecture diagram to documentation

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
FileDescription
functions/utils/video-processing.mjsEnhanced timeToSeconds to parse milliseconds with comma separator
functions/utils/transcripts.mjsAdded null-safe millisecond handling to timeToSeconds
functions/clips/get-clip.mjsImplemented SRT file loading from S3 and time-range-based transcript extraction with fallback logic
functions/agents/clip-detector.mjsUpdated prompt examples to include millisecond timestamps and improved JSON structure
docs/architecture-diagrams.mdAdded new simplified architecture diagram in Mermaid format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadfunctions/clips/get-clip.mjs
Comment threadfunctions/clips/get-clip.mjs Outdated
const parts = timeStr.split(':').map(part => parseInt(part, 10));
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The milliseconds parsing logic doesn't handle base 10 correctly. The parseInt function should explicitly specify base 10 as the second parameter. Without it, strings with leading zeros like "060" might be parsed incorrectly in some JavaScript environments. Use parseInt(msPart, 10) instead of parseInt(msPart).

Suggested change
constmilliseconds=msPart ? parseInt(msPart)/1000 : 0;
constmilliseconds=msPart ? parseInt(msPart,10)/1000 : 0;

Copilot uses AI. Check for mistakes.
return hours * 3600 + minutes * 60 + seconds;
return hours * 3600 + minutes * 60 + seconds + milliseconds;
} else {
throw new Error('Time string must be in HH:MM:SS or MM:SS format');

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message states 'Time string must be in HH:MM:SS or MM:SS format' but this is now outdated. The function now supports milliseconds with the format HH:MM:SS,mmm or MM:SS,mmm. The error message should be updated to reflect this: 'Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format'.

Suggested change
thrownewError('Time string must be in HH:MM:SSor MM:SS format');
thrownewError('Time string must be in HH:MM:SS, MM:SS, HH:MM:SS,mmm, or MM:SS,mmm format');

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
const [timePart, msPart] = timeStr.split(',');
const parts = timePart.split(':').map(Number);
const milliseconds = msPart ? parseInt(msPart) / 1000 : 0;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new millisecond support in timeToSeconds functions is not adequately tested. The existing tests in tests/unit/utils/video-processing.test.js only test the HH:MM:SS and MM:SS formats without milliseconds. Tests should be added to verify parsing of HH:MM:SS,mmm and MM:SS,mmm formats, including edge cases like '00:00:00,000', '01:30:45,500', and '10:00,100'.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment threadfunctions/clips/get-clip.mjs Outdated
Comment on lines +78 to +90
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

if (relevantEntries.length > 0) {
// Use the full SRT text (preserves per-entry speaker labels where present)
const text = relevantEntries.map(e => e.text).join(' ');
return text;

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT loading and transcript extraction logic doesn't handle potential errors from timeToSeconds if the segment timestamps don't match the expected format. If segments have timestamps without milliseconds (HH:MM:SS format) but srtEntries have timestamps with milliseconds (HH:MM:SS,mmm format from SRT files), the timeToSeconds function will work for both. However, if there's a format mismatch or invalid timestamp, the function will throw an error that's not caught here, causing the entire handler to fail. Consider wrapping the timeToSeconds calls in a try-catch block or adding validation to ensure consistent formats.

Suggested change
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
try{
constsegStart=timeToSeconds(segment.startTime);
constsegEnd=timeToSeconds(segment.endTime);
constrelevantEntries=srtEntries.filter(entry=>{
constentryStart=timeToSeconds(entry.startTime);
constentryEnd=timeToSeconds(entry.endTime);
returnentryStart<segEnd&&entryEnd>segStart;
});
if(relevantEntries.length>0){
// Use the full SRT text (preserves per-entry speaker labels where present)
consttext=relevantEntries.map(e=>e.text).join(' ');
returntext;
}
}catch(err){
logger.warn('Failed to parse timestamps for SRT transcript extraction, falling back to stored text',{
error: err.message,
episodeId,
tenantId,
clipId,
segment
});

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
if (srtEntries.length > 0) {
const segStart = timeToSeconds(segment.startTime);
const segEnd = timeToSeconds(segment.endTime);

const relevantEntries = srtEntries.filter(entry => {
const entryStart = timeToSeconds(entry.startTime);
const entryEnd = timeToSeconds(entry.endTime);
return entryStart < segEnd && entryEnd > segStart;
});

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRT file is loaded from S3 on every get-clip request, and then every segment's time range is compared against all SRT entries using filter operations. For clips with multiple segments and large SRT files (hundreds of entries), this results in O(segments × entries) time complexity. Consider caching the parsed SRT entries or implementing a more efficient lookup strategy (e.g., building a time-based index). Alternatively, document that this is acceptable for the expected scale of operations.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

const [time, ms] = timeStr.split(',');
const [hours, minutes, seconds] = time.split(':').map(Number);
return hours * 3600 + minutes * 60 + seconds + parseInt(ms) / 1000;
return hours * 3600 + minutes * 60 + seconds + (ms ? parseInt(ms) / 1000 : 0);

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseInt function should explicitly specify base 10 as the second parameter to ensure consistent parsing. Use parseInt(ms, 10) instead of parseInt(ms) to avoid potential issues with strings that have leading zeros.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +200 to +213
{
"startTime": "00:14:32,000",
"endTime": "00:15:18,500",
"speaker": "Allen",
"order": 1,
"transcript": "Did you know agents could do this? I was blown away the first time I saw it work end-to-end. You basically hand it a tool and it figures out the rest — no scaffolding, no hand-holding. It just goes. And the crazy part is it gets it right most of the time."
},
{
"startTime": "00:41:01,000",
"endTime": "00:41:05,200",
"speaker": "Andres",
"order": 2,
"transcript": "No I didn't, but now we can use it in production."
}

CopilotAIFeb 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example timestamps in the prompt now include milliseconds (e.g., "00:14:32,000"), but there's an inconsistency with the broader codebase. The global TimestampSchema in schemas/common.mjs still only accepts HH:MM:SS format without milliseconds (/^\d{2}:\d{2}:\d{2}$/), and tests explicitly verify this. While the create-clips tool schema was updated locally to accept milliseconds, this creates a potential validation mismatch. If segments are stored with millisecond timestamps, they may fail validation in other parts of the system that use the global schema. Consider updating the global TimestampSchema or documenting why some timestamps have milliseconds while others don't.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #38, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAIand others added 2 commits February 18, 2026 19:47
Co-authored-by: andmoredev <33256364+andmoredev@users.noreply.github.com>
Fix inconsistent speaker label handling in clip transcripts

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #39, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #40, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #41, to work on those changes. Once the pull request is ready, I'll request review from you.

CopilotAI commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

@andmoredev I've opened a new pull request, #42, to work on those changes. Once the pull request is ready, I'll request review from you.

@andmoredev
andmoredev merged commit c24a551 into mainFeb 18, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andmoredev