# Meeting agenda — local source

Download `meeting-agenda.mjs` alongside this README. Import
`buildMeetingAgenda(csv, title, start, budget)` in a JavaScript ES-module
environment. All four arguments are strings. The module exports only this
function and returns `{ text, topics, totalMinutes, missingOwners, overBudget }`.
`text` contains the complete timed agenda and manual Docs review checklist.

Prepare a comma-delimited CSV from your Forms topic responses with exactly the
unique lowercase headers `topic,owner,minutes`; their order may vary. Native
Forms response exports usually have other columns: manually select/rename these
three columns first. Include 1–50 topic rows. CSV quoting, escaped double quotes,
commas within quoted fields and CRLF/CR/LF record separators are supported. One
final record separator is allowed; blank internal rows and extra fields fail.

Topic text must be nonblank and at most 200 characters. Owner text may be blank
(including ordinary spaces), in which case the agenda displays `[owner needed]`
and adds an assignment checklist item; otherwise it is at most 120 characters.
The title must be nonblank and at most 120 characters. These labels cannot contain
tabs, line breaks, control characters or Unicode line/paragraph separators.
Nonblank labels retain their literal spaces and punctuation; no formulas,
templates, HTML or links are evaluated.

Each topic needs a positive decimal integer from 1–180 minutes. The meeting
budget is a positive decimal integer from 1–480 minutes. Both forbid signs,
fractions, leading zeroes and whitespace. Start time is strict 24-hour `HH:MM`
from `00:00` to `23:59`. Total duration must be at most 480 minutes, and the agenda
must finish before midnight on the same day. The tool does not infer a date or
timezone. Exceeding the chosen budget produces a conspicuous warning and review
item; it does not shorten topics. Invalid input throws before a result is
returned. There are no partial results or silently clipped rows. CSV input is
limited to 100,000 characters by the shared strict parser.

## Executable fictional example

Save this code as `example.mjs` beside the downloaded module and run
`node example.mjs` (Node.js 18 or newer). It creates a 35-minute agenda with one
unassigned owner and a five-minute budget overrun.

```js
import { buildMeetingAgenda } from './meeting-agenda.mjs';
const csv = [
  'topic,owner,minutes',
  'Review open actions,Alex,10',
  'Agree next milestones,,25',
].join('\n');
const result = buildMeetingAgenda(csv, 'Weekly project check-in', '09:00', '30');
console.log(`Topics: ${result.topics}; minutes: ${result.totalMinutes}; missing owners: ${result.missingOwners}; over budget: ${result.overBudget}`);
console.log(result.text.split('\n').find(line => line.startsWith('OVER BUDGET')));
console.log(result.text.split('\n').find(line => line.startsWith('2. ')));
// result.text is the complete agenda to review and copy manually into Docs.
```

Expected exact console output:

```text
Topics: 2; minutes: 35; missing owners: 1; over budget: true
OVER BUDGET by 5 minutes. Resolve the timeboxes before sharing.
2. 09:10-09:35 (25 min) | Agree next milestones | Owner: [owner needed]
```

## Manual review and privacy

Compare the agenda with the original responses, assign missing owners, confirm
the meeting date/timezone and resolve the budget warning. Review the literal
text, then copy the complete draft into a Google Doc. Check the Doc permissions
and share it yourself. Breaks and transition time count only if you include
them as topic rows. A valid agenda does not establish response completeness,
participant availability, acceptance or actual meeting outcomes.

The dependency-free module has no network, filesystem, process, secret access,
telemetry, Google connection, document creation, sharing or sending. Calling
code controls storage and transmission: an agent, logger or surrounding app may
retain or transmit your input. Choose an appropriate local environment for
private response data. This fictional executable example is QA, not evidence
of independent use, customer completion or demand.

## License

MIT License

Copyright (c) 2026 QuasiLife

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
