Repository: go-gitea/gitea
File: web_src/js/components/RepoActionView.vue (Vue)

Code before:
import {addDelegatedEventListener, createElementFromAttrs, toggleElem} from '../utils/dom.ts';
import {formatDatetime} from '../utils/time.ts';
import {renderAnsi} from '../render/ansi.ts';
import {POST, DELETE} from '../modules/fetch.ts';
import type {IntervalId} from '../types.ts';
import {toggleFullScreen} from '../utils.ts';
import {localUserSettings} from '../modules/user-settings.ts';

// see "models/actions/status.go", if it needs to be used somewhere else, move it to a shared file like "types/actions.ts"
type RunStatus = 'unknown' | 'waiting' | 'running' | 'success' | 'failure' | 'cancelled' | 'skipped' | 'blocked';

type StepContainerElement = HTMLElement & {_stepLogsActiveContainer?: HTMLElement}

export type LogLine = {
  index: number;
  timestamp: number;
  message: string;
};

const LogLinePrefixesGroup = ['::group::', '##[group]'];
const LogLinePrefixesEndGroup = ['::endgroup::', '##[endgroup]'];
const LogLinePrefixesHidden = ['::add-matcher::', '##[add-matcher]', '::remove-matcher'];

type LogLineCommand = {
  name: 'group' | 'endgroup',
  prefix: string,
}

type Job = {
  id: number;
  name: string;
  status: RunStatus;
  canRerun: boolean;
  duration: string;
}

type Step = {
  summary: string,
  duration: string,
  status: RunStatus,
}

type JobStepState = {
  cursor: string|null,
  expanded: boolean,
  manuallyCollapsed: boolean, // whether the user manually collapsed the step, used to avoid auto-expanding it again
}

function parseLineCommand(line: LogLine): LogLineCommand | null {
  for (const prefix of LogLinePrefixesGroup) {
    if (line.message.startsWith(prefix)) {

Review comment (suggestion):
```suggestion
// https://github.com/actions/toolkit/blob/master/docs/commands.md
// https://github.com/actions/runner/blob/main/docs/adrs/0276-problem-matchers.md#registration
// Although there should be no `##[add-matcher]` syntax, there are still such outputs when using act-runner
const LogLinePrefixesHidden = ['::add-matcher::', '##[add-matcher]', '::remove-matcher'];
```

Code after:
import {addDelegatedEventListener, createElementFromAttrs, toggleElem} from '../utils/dom.ts';
import {formatDatetime} from '../utils/time.ts';
import {renderAnsi} from '../render/ansi.ts';
import {POST, DELETE} from '../modules/fetch.ts';
import type {IntervalId} from '../types.ts';
import {toggleFullScreen} from '../utils.ts';
import {localUserSettings} from '../modules/user-settings.ts';

// see "models/actions/status.go", if it needs to be used somewhere else, move it to a shared file like "types/actions.ts"
type RunStatus = 'unknown' | 'waiting' | 'running' | 'success' | 'failure' | 'cancelled' | 'skipped' | 'blocked';

type StepContainerElement = HTMLElement & {_stepLogsActiveContainer?: HTMLElement}

export type LogLine = {
  index: number;
  timestamp: number;
  message: string;
};

// `##[group]` is from Azure Pipelines, just supported by the way. https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands
const LogLinePrefixesGroup = ['::group::', '##[group]'];
const LogLinePrefixesEndGroup = ['::endgroup::', '##[endgroup]'];
// https://github.com/actions/toolkit/blob/master/docs/commands.md
// https://github.com/actions/runner/blob/main/docs/adrs/0276-problem-matchers.md#registration
// Although there should be no `##[add-matcher]` syntax, there are still such outputs when using act-runner
const LogLinePrefixesHidden = ['::add-matcher::', '##[add-matcher]', '::remove-matcher'];

type LogLineCommand = {
  name: 'group' | 'endgroup',
  prefix: string,
}

type Job = {
  id: number;
  name: string;
  status: RunStatus;
  canRerun: boolean;
  duration: string;
}

type Step = {
  summary: string,
  duration: string,
  status: RunStatus,
}

type JobStepState = {
  cursor: string|null,
  expanded: boolean,
  manuallyCollapsed: boolean, // whether the user manually collapsed the step, used to avoid auto-expanding it again
}