feat(lib-core): biblioteca atomica @pulse-libs/core v1.0.0-beta.1

Esta commit conteudo a estrutura atomica completa:

- types:     Result<T,E>, AsyncState<T>, Paginated<T>, SortConfig<T>
- utils:     date, str, num, cn, debounce, throttle, storage, arr, obj
- validators: Zod schemas — email, password, uuid, url, phone, CPF/CNPJ, sanitizedStr, safeParse
- hooks:     useToggle, useAsync, useDebounce, useLocalStorage, useMedia, useInterval, useOnClickOutside, useClipboard, useFetch
- components: Button, Input, Alert, Card, Spinner (atomic design pattern)
- build:     tsup v8 ESM+CJS + DTS + sourcemaps — 0 erros
- tests:     57 testes 100% usuarios
- docker:    multi-stage Dockerfile (node 20-alpine)
- config:    vitest, tsup, tsconfig strict, .npmignore

Filosofia atomica:/utils ← /types ← /validators ← /hooks ← /components
Build: npm run build | Test: npm test | Publish: npm publish

🤖 Generated with Pulse (openclaw + nova-self-improver)
This commit is contained in:
pulse-agent
2026-05-19 21:43:03 -03:00
parent ae39e45460
commit bbdb68a6de
7030 changed files with 2040595 additions and 0 deletions
@@ -0,0 +1,109 @@
#!/usr/bin/env node
/**
* export-projects-overview.mjs (taskflow-009)
*
* Reads the TaskFlow SQLite DB and emits a clean JSON summary to stdout.
*
* Output shape:
* {
* exported_at: ISO string,
* projects: [ { id, name, description, status, task_counts, progress_pct } ],
* recent_transitions: [ { task_id, from_status, to_status, reason, at } ]
* }
*
* Usage:
* node scripts/export-projects-overview.mjs
* node scripts/export-projects-overview.mjs | jq .
*/
import { DatabaseSync } from 'node:sqlite'
import path from 'node:path'
import { existsSync } from 'node:fs'
// ── DB path resolution ─────────────────────────────────────────────────────
const workspace = process.env.OPENCLAW_WORKSPACE || process.cwd()
const dbPath = path.join(workspace, 'memory', 'taskflow.sqlite')
if (!existsSync(dbPath)) {
process.stderr.write(
`[taskflow-export] DB not found at: ${dbPath}\n` +
` Run 'taskflow init' to bootstrap the database.\n`
)
process.exit(1)
}
const db = new DatabaseSync(dbPath)
db.exec('PRAGMA foreign_keys = ON')
db.exec('PRAGMA journal_mode = WAL')
// ── Fetch projects ─────────────────────────────────────────────────────────
const projects = db
.prepare('SELECT id, name, description, status FROM projects ORDER BY id')
.all()
// ── Task counts per project ────────────────────────────────────────────────
const ALL_STATUSES = ['in_progress', 'pending_validation', 'backlog', 'blocked', 'done']
const countRows = db
.prepare(`
SELECT project_id, status, COUNT(*) AS cnt
FROM tasks_v2
GROUP BY project_id, status
`)
.all()
// Build lookup: { project_id: { status: count } }
const countsByProject = {}
for (const row of countRows) {
if (!countsByProject[row.project_id]) countsByProject[row.project_id] = {}
countsByProject[row.project_id][row.status] = row.cnt
}
// ── Assemble project objects ───────────────────────────────────────────────
const projectsOut = projects.map((p) => {
const counts = countsByProject[p.id] || {}
const task_counts = {
in_progress: counts.in_progress ?? 0,
pending_validation: counts.pending_validation ?? 0,
backlog: counts.backlog ?? 0,
blocked: counts.blocked ?? 0,
done: counts.done ?? 0,
}
const total = Object.values(task_counts).reduce((s, n) => s + n, 0)
const progress_pct = total > 0
? Math.round((task_counts.done / total) * 10000) / 100 // 2 decimal places
: 0
return {
id: p.id,
name: p.name,
description: p.description,
status: p.status,
task_counts,
progress_pct,
}
})
// ── Recent transitions (last 20) ───────────────────────────────────────────
const recentTransitions = db
.prepare(`
SELECT task_id, from_status, to_status, reason, at
FROM task_transitions_v2
ORDER BY id DESC
LIMIT 20
`)
.all()
// Reverse so oldest-first within the window (more natural for consumers)
recentTransitions.reverse()
// ── Output ─────────────────────────────────────────────────────────────────
const output = {
exported_at: new Date().toISOString(),
projects: projectsOut,
recent_transitions: recentTransitions,
}
process.stdout.write(JSON.stringify(output, null, 2) + '\n')