checkpoint: pre-split branch cleanup
This commit is contained in:
parent
4c2ae2e5b7
commit
b5db7a7753
276 changed files with 35912 additions and 60119 deletions
|
|
@ -1,140 +1,140 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* bb-init.mjs - Agent Session Bootstrapper (Lease-Based)
|
||||
*
|
||||
* Part of Operative Protocol v1 (bb-u6f.6.3)
|
||||
*
|
||||
* Responsibility:
|
||||
* 1. Resolve bb.ps1 path.
|
||||
* 2. Identify agent (adopt or register).
|
||||
* 3. Start the initial activity lease.
|
||||
*
|
||||
* Note: No background processes are spawned. Liveness is maintained
|
||||
* via passive side-effects of CLI commands (Activity-based model).
|
||||
*/
|
||||
|
||||
import { parseArgs } from 'node:util';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { execSync, execFileSync } from 'node:child_process';
|
||||
|
||||
function log(obj) {
|
||||
process.stdout.write(`${JSON.stringify(obj, null, 2)}
|
||||
`);
|
||||
}
|
||||
|
||||
function error(code, message) {
|
||||
log({ ok: false, error: { code, message } });
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function getUncommittedChanges(projectRoot) {
|
||||
try {
|
||||
const out = execSync('git status --porcelain', { cwd: projectRoot, encoding: 'utf8' });
|
||||
return out.split('\n')
|
||||
.filter(Boolean)
|
||||
.map(line => line.slice(3).trim())
|
||||
.filter(p => !p.startsWith('.beadboard') && !p.startsWith('.beads'));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveBbPath() {
|
||||
const envRepo = process.env.BB_REPO;
|
||||
|
||||
const tsEntry = path.join(process.cwd(), 'tools', 'bb.ts');
|
||||
try {
|
||||
await fs.access(tsEntry);
|
||||
return { type: 'tsx', path: tsEntry };
|
||||
} catch {}
|
||||
|
||||
if (envRepo) {
|
||||
const p = path.join(envRepo, 'bb.ps1');
|
||||
try {
|
||||
await fs.access(p);
|
||||
return { type: 'powershell', path: p };
|
||||
} catch {}
|
||||
|
||||
const envTs = path.join(envRepo, 'tools', 'bb.ts');
|
||||
try {
|
||||
await fs.access(envTs);
|
||||
return { type: 'tsx', path: envTs };
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { values } = parseArgs({
|
||||
options: {
|
||||
'non-interactive': { type: 'boolean' },
|
||||
adopt: { type: 'string' },
|
||||
register: { type: 'string' },
|
||||
role: { type: 'string' },
|
||||
json: { type: 'boolean' },
|
||||
'project-root': { type: 'string' }
|
||||
}
|
||||
});
|
||||
|
||||
const isNonInteractive = values['non-interactive'];
|
||||
const projectRoot = values['project-root'] || process.cwd();
|
||||
const bbResult = await resolveBbPath();
|
||||
|
||||
if (!bbResult) {
|
||||
error('BB_NOT_FOUND', 'Could not resolve bb.ps1 or tools/bb.ts');
|
||||
}
|
||||
|
||||
let agentId = values.adopt || values.register;
|
||||
let mode = values.adopt ? 'adopt' : (values.register ? 'register' : 'auto');
|
||||
|
||||
if (mode === 'auto' && isNonInteractive) {
|
||||
error('AMBIGUOUS_SESSION', 'In non-interactive mode, --adopt or --register is required.');
|
||||
}
|
||||
|
||||
if (mode === 'adopt') {
|
||||
const changes = await getUncommittedChanges(projectRoot);
|
||||
if (changes.length === 0 && isNonInteractive) {
|
||||
error('ADOPTION_REJECTED', 'No evidence (uncommitted changes) to support identity adoption.');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Compose environment fingerprint (Rig)
|
||||
const rigId = `${os.platform()}-${os.arch()}-${os.hostname()}`;
|
||||
|
||||
const env = { ...process.env, BD_DB: path.join(projectRoot, '.beads', 'beads.db') };
|
||||
|
||||
if (mode === 'register') {
|
||||
const role = values.role || 'agent';
|
||||
const registerArgs = bbResult.type === 'tsx'
|
||||
? ['tsx', bbResult.path, 'agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json']
|
||||
: ['agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json'];
|
||||
const registerCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
|
||||
execFileSync(registerCmd, registerArgs, { stdio: 'ignore', cwd: projectRoot, env });
|
||||
} else {
|
||||
// Start/Extend the lease to show we are now active
|
||||
const leaseArgs = bbResult.type === 'tsx'
|
||||
? ['tsx', bbResult.path, 'agent', 'activity-lease', '--agent', agentId, '--json']
|
||||
: ['agent', 'activity-lease', '--agent', agentId, '--json'];
|
||||
const leaseCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
|
||||
execFileSync(leaseCmd, leaseArgs, { stdio: 'ignore', cwd: projectRoot, env });
|
||||
}
|
||||
|
||||
log({
|
||||
ok: true,
|
||||
agent_id: agentId,
|
||||
mode,
|
||||
lease: { status: 'active', note: 'Activity lease started. Liveness maintained via real work.' },
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
error('INIT_FAILED', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* bb-init.mjs - Agent Session Bootstrapper (Lease-Based)
|
||||
*
|
||||
* Part of Operative Protocol v1 (bb-u6f.6.3)
|
||||
*
|
||||
* Responsibility:
|
||||
* 1. Resolve bb.ps1 path.
|
||||
* 2. Identify agent (adopt or register).
|
||||
* 3. Start the initial activity lease.
|
||||
*
|
||||
* Note: No background processes are spawned. Liveness is maintained
|
||||
* via passive side-effects of CLI commands (Activity-based model).
|
||||
*/
|
||||
|
||||
import { parseArgs } from 'node:util';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { execSync, execFileSync } from 'node:child_process';
|
||||
|
||||
function log(obj) {
|
||||
process.stdout.write(`${JSON.stringify(obj, null, 2)}
|
||||
`);
|
||||
}
|
||||
|
||||
function error(code, message) {
|
||||
log({ ok: false, error: { code, message } });
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function getUncommittedChanges(projectRoot) {
|
||||
try {
|
||||
const out = execSync('git status --porcelain', { cwd: projectRoot, encoding: 'utf8' });
|
||||
return out.split('\n')
|
||||
.filter(Boolean)
|
||||
.map(line => line.slice(3).trim())
|
||||
.filter(p => !p.startsWith('.beadboard') && !p.startsWith('.beads'));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveBbPath() {
|
||||
const envRepo = process.env.BB_REPO;
|
||||
|
||||
const tsEntry = path.join(process.cwd(), 'tools', 'bb.ts');
|
||||
try {
|
||||
await fs.access(tsEntry);
|
||||
return { type: 'tsx', path: tsEntry };
|
||||
} catch {}
|
||||
|
||||
if (envRepo) {
|
||||
const p = path.join(envRepo, 'bb.ps1');
|
||||
try {
|
||||
await fs.access(p);
|
||||
return { type: 'powershell', path: p };
|
||||
} catch {}
|
||||
|
||||
const envTs = path.join(envRepo, 'tools', 'bb.ts');
|
||||
try {
|
||||
await fs.access(envTs);
|
||||
return { type: 'tsx', path: envTs };
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { values } = parseArgs({
|
||||
options: {
|
||||
'non-interactive': { type: 'boolean' },
|
||||
adopt: { type: 'string' },
|
||||
register: { type: 'string' },
|
||||
role: { type: 'string' },
|
||||
json: { type: 'boolean' },
|
||||
'project-root': { type: 'string' }
|
||||
}
|
||||
});
|
||||
|
||||
const isNonInteractive = values['non-interactive'];
|
||||
const projectRoot = values['project-root'] || process.cwd();
|
||||
const bbResult = await resolveBbPath();
|
||||
|
||||
if (!bbResult) {
|
||||
error('BB_NOT_FOUND', 'Could not resolve bb.ps1 or tools/bb.ts');
|
||||
}
|
||||
|
||||
let agentId = values.adopt || values.register;
|
||||
let mode = values.adopt ? 'adopt' : (values.register ? 'register' : 'auto');
|
||||
|
||||
if (mode === 'auto' && isNonInteractive) {
|
||||
error('AMBIGUOUS_SESSION', 'In non-interactive mode, --adopt or --register is required.');
|
||||
}
|
||||
|
||||
if (mode === 'adopt') {
|
||||
const changes = await getUncommittedChanges(projectRoot);
|
||||
if (changes.length === 0 && isNonInteractive) {
|
||||
error('ADOPTION_REJECTED', 'No evidence (uncommitted changes) to support identity adoption.');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Compose environment fingerprint (Rig)
|
||||
const rigId = `${os.platform()}-${os.arch()}-${os.hostname()}`;
|
||||
|
||||
const env = { ...process.env, BD_DB: path.join(projectRoot, '.beads', 'beads.db') };
|
||||
|
||||
if (mode === 'register') {
|
||||
const role = values.role || 'agent';
|
||||
const registerArgs = bbResult.type === 'tsx'
|
||||
? ['tsx', bbResult.path, 'agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json']
|
||||
: ['agent', 'register', '--name', agentId, '--role', role, '--rig', rigId, '--json'];
|
||||
const registerCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
|
||||
execFileSync(registerCmd, registerArgs, { stdio: 'ignore', cwd: projectRoot, env });
|
||||
} else {
|
||||
// Start/Extend the lease to show we are now active
|
||||
const leaseArgs = bbResult.type === 'tsx'
|
||||
? ['tsx', bbResult.path, 'agent', 'activity-lease', '--agent', agentId, '--json']
|
||||
: ['agent', 'activity-lease', '--agent', agentId, '--json'];
|
||||
const leaseCmd = bbResult.type === 'tsx' ? 'npx' : bbResult.path;
|
||||
execFileSync(leaseCmd, leaseArgs, { stdio: 'ignore', cwd: projectRoot, env });
|
||||
}
|
||||
|
||||
log({
|
||||
ok: true,
|
||||
agent_id: agentId,
|
||||
mode,
|
||||
lease: { status: 'active', note: 'Activity lease started. Liveness maintained via real work.' },
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
error('INIT_FAILED', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
@ -1,41 +1,41 @@
|
|||
import { chromium } from 'playwright';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
const url = process.argv[2];
|
||||
if (!url) {
|
||||
console.error('Usage: node scripts/capture-graph.mjs <url>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const outputDir = path.join('artifacts');
|
||||
await fs.mkdir(outputDir, { recursive: true });
|
||||
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
|
||||
async function screenshot(name, viewport, prepare) {
|
||||
const page = await browser.newPage({ viewport });
|
||||
await page.goto(url, { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(1000);
|
||||
if (prepare) {
|
||||
await prepare(page);
|
||||
await page.waitForTimeout(450);
|
||||
}
|
||||
await page.screenshot({
|
||||
path: path.join(outputDir, name),
|
||||
fullPage: true,
|
||||
});
|
||||
await page.close();
|
||||
}
|
||||
|
||||
await screenshot('graph-next-1440.png', { width: 1440, height: 900 });
|
||||
await screenshot('graph-next-768.png', { width: 768, height: 1024 });
|
||||
await screenshot('graph-next-390-overview.png', { width: 390, height: 844 });
|
||||
await screenshot('graph-next-390-flow.png', { width: 390, height: 844 }, async (page) => {
|
||||
const flowButton = page.getByRole('button', { name: 'Switch to Graph' });
|
||||
if (await flowButton.count()) {
|
||||
await flowButton.first().click();
|
||||
}
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
import { chromium } from 'playwright';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
const url = process.argv[2];
|
||||
if (!url) {
|
||||
console.error('Usage: node scripts/capture-graph.mjs <url>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const outputDir = path.join('artifacts');
|
||||
await fs.mkdir(outputDir, { recursive: true });
|
||||
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
|
||||
async function screenshot(name, viewport, prepare) {
|
||||
const page = await browser.newPage({ viewport });
|
||||
await page.goto(url, { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(1000);
|
||||
if (prepare) {
|
||||
await prepare(page);
|
||||
await page.waitForTimeout(450);
|
||||
}
|
||||
await page.screenshot({
|
||||
path: path.join(outputDir, name),
|
||||
fullPage: true,
|
||||
});
|
||||
await page.close();
|
||||
}
|
||||
|
||||
await screenshot('graph-next-1440.png', { width: 1440, height: 900 });
|
||||
await screenshot('graph-next-768.png', { width: 768, height: 1024 });
|
||||
await screenshot('graph-next-390-overview.png', { width: 390, height: 844 });
|
||||
await screenshot('graph-next-390-flow.png', { width: 390, height: 844 }, async (page) => {
|
||||
const flowButton = page.getByRole('button', { name: 'Switch to Graph' });
|
||||
if (await flowButton.count()) {
|
||||
await flowButton.first().click();
|
||||
}
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
|
|
|
|||
|
|
@ -1,31 +1,31 @@
|
|||
import { chromium } from 'playwright';
|
||||
import path from 'node:path';
|
||||
|
||||
const url = process.argv[2];
|
||||
const mode = process.argv[3];
|
||||
|
||||
if (!url || !mode) {
|
||||
console.error('Usage: node scripts/capture-kanban.mjs <url> <before|after>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const shots = [
|
||||
{ name: 'mobile', width: 390, height: 844 },
|
||||
{ name: 'tablet', width: 768, height: 1024 },
|
||||
{ name: 'desktop', width: 1440, height: 900 },
|
||||
];
|
||||
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
|
||||
for (const shot of shots) {
|
||||
const page = await browser.newPage({ viewport: { width: shot.width, height: shot.height } });
|
||||
await page.goto(url, { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(700);
|
||||
await page.screenshot({
|
||||
path: path.join('artifacts', `kanban-${shot.name}-${mode}.png`),
|
||||
fullPage: true,
|
||||
});
|
||||
await page.close();
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
import { chromium } from 'playwright';
|
||||
import path from 'node:path';
|
||||
|
||||
const url = process.argv[2];
|
||||
const mode = process.argv[3];
|
||||
|
||||
if (!url || !mode) {
|
||||
console.error('Usage: node scripts/capture-kanban.mjs <url> <before|after>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const shots = [
|
||||
{ name: 'mobile', width: 390, height: 844 },
|
||||
{ name: 'tablet', width: 768, height: 1024 },
|
||||
{ name: 'desktop', width: 1440, height: 900 },
|
||||
];
|
||||
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
|
||||
for (const shot of shots) {
|
||||
const page = await browser.newPage({ viewport: { width: shot.width, height: shot.height } });
|
||||
await page.goto(url, { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForTimeout(700);
|
||||
await page.screenshot({
|
||||
path: path.join('artifacts', `kanban-${shot.name}-${mode}.png`),
|
||||
fullPage: true,
|
||||
});
|
||||
await page.close();
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue