drafted 1.14.2 → 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/drafted.mjs +15 -4
- package/mcp/server.mjs +11 -1
- package/package.json +1 -1
- package/src/shared/minion-presets.mjs +67 -0
package/cli/drafted.mjs
CHANGED
|
@@ -579,10 +579,22 @@ program
|
|
|
579
579
|
|
|
580
580
|
// Start server in background
|
|
581
581
|
const serverPath = join(__dirname, '../server/server.mjs');
|
|
582
|
-
const { openSync } = await import('fs');
|
|
583
|
-
const outLog = openSync(join(DEFAULT_STATE_DIR, 'server.log'), 'w');
|
|
584
582
|
const tsxPath = join(__dirname, '../node_modules/.bin/tsx');
|
|
585
583
|
const instrumentPath = join(__dirname, '../server/instrument.mjs');
|
|
584
|
+
// A global `npm install -g drafted` only ships the CLI/MCP client (see
|
|
585
|
+
// package.json "files") — the Express server and its src/db, src/auth,
|
|
586
|
+
// src/middleware sources, plus the tsx devDependency needed to run them,
|
|
587
|
+
// are not part of that install. This only works from a full git checkout.
|
|
588
|
+
if (!existsSync(tsxPath) || !existsSync(serverPath)) {
|
|
589
|
+
console.error('Error: cannot start the server from this installation.');
|
|
590
|
+
console.error('This looks like a global `npm install -g drafted` install, which ships only the CLI/MCP client, not the full server.');
|
|
591
|
+
console.error('To bring the local server back up, either:');
|
|
592
|
+
console.error(' - reopen the Drafted desktop app, or');
|
|
593
|
+
console.error(' - run from a full source checkout: git clone the drafted repo, then `npm install && npm run dev`');
|
|
594
|
+
process.exit(1);
|
|
595
|
+
}
|
|
596
|
+
const { openSync } = await import('fs');
|
|
597
|
+
const outLog = openSync(join(DEFAULT_STATE_DIR, 'server.log'), 'w');
|
|
586
598
|
const child = spawn(tsxPath, ['--import', instrumentPath, serverPath], {
|
|
587
599
|
detached: true,
|
|
588
600
|
stdio: ['ignore', outLog, outLog],
|
|
@@ -647,11 +659,10 @@ program
|
|
|
647
659
|
console.log('✅ Drafted server is running');
|
|
648
660
|
console.log(` PID: ${pid}`);
|
|
649
661
|
console.log(` URL: http://localhost:${port}`);
|
|
650
|
-
console.log(` Frames: ${state.frames.length}`);
|
|
651
662
|
|
|
652
663
|
// Try to ping server
|
|
653
664
|
try {
|
|
654
|
-
const response = await authFetch(`http://localhost:${
|
|
665
|
+
const response = await authFetch(`http://localhost:${port}/status`);
|
|
655
666
|
const data = await response.json();
|
|
656
667
|
console.log(` Status: ${data.status}`);
|
|
657
668
|
} catch (error) {
|
package/mcp/server.mjs
CHANGED
|
@@ -1572,7 +1572,17 @@ if (!isRemote) tool('auth', 'Sign in to Drafted. On a local install the DESKTOP
|
|
|
1572
1572
|
const sid = await waitForBootstrapAuth(Date.now() + 180000);
|
|
1573
1573
|
if (!sid) throw new Error('Timed out waiting for sign-in. Complete sign-in in the Drafted app window, then retry.');
|
|
1574
1574
|
getState().sessionId = null;
|
|
1575
|
-
|
|
1575
|
+
// cloneSession() can fail transiently right after the app plants the bootstrap
|
|
1576
|
+
// session (e.g. the server hasn't finished committing it yet) — retry briefly
|
|
1577
|
+
// before giving up, and never report logged_in unless a session actually landed.
|
|
1578
|
+
let cloned = await cloneSession();
|
|
1579
|
+
for (let attempt = 0; !cloned && attempt < 3; attempt++) {
|
|
1580
|
+
await new Promise((r) => setTimeout(r, 750));
|
|
1581
|
+
cloned = await cloneSession();
|
|
1582
|
+
}
|
|
1583
|
+
if (!cloned || !getState().sessionId) {
|
|
1584
|
+
throw new Error('Signed in, but could not establish a session yet. Retry your request in a moment.');
|
|
1585
|
+
}
|
|
1576
1586
|
connectAgentWs();
|
|
1577
1587
|
return ok({ status: 'logged_in', via: 'desktop-app' });
|
|
1578
1588
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.3",
|
|
4
4
|
"description": "Drafted — visual thinking surface for humans and AI agents. Renders HTML, markdown, images, and code as frames on a zoomable canvas, with MCP tools for AI agents and real-time sync for humans.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Deploy-seeded starting points for the Minion builder ("presets"). Pure data,
|
|
2
|
+
// shared for every org (no per-org copy). Each preset pre-wires the builder
|
|
3
|
+
// config for a use case; the user then edits any field. `config: null` means
|
|
4
|
+
// the full blank/advanced form. See feature card: contexts/minions/feature-card.
|
|
5
|
+
//
|
|
6
|
+
// A preset's `config` is a partial minion the builder hydrates via showConfig:
|
|
7
|
+
// { description, checklist:[{label,evidence,required}], output:{mode,grouping,format,register} }
|
|
8
|
+
// Drive-only bits (format:google-*, register) degrade to a markdown record when
|
|
9
|
+
// the org has no Google Drive connected — the builder simply hides those fields.
|
|
10
|
+
export const MINION_PRESETS = [
|
|
11
|
+
{
|
|
12
|
+
key: 'reports-sheet',
|
|
13
|
+
name: 'Collect reports → spreadsheet',
|
|
14
|
+
icon: '▤',
|
|
15
|
+
tagline: 'A form people fill out. Each one becomes a document + a new row in a master sheet.',
|
|
16
|
+
config: {
|
|
17
|
+
description: '',
|
|
18
|
+
checklist: [
|
|
19
|
+
{ label: 'Department', evidence: 'text', required: true },
|
|
20
|
+
{ label: 'What happened', evidence: 'text', required: true },
|
|
21
|
+
{ label: 'Attachment (file or photo)', evidence: 'file', required: false },
|
|
22
|
+
],
|
|
23
|
+
output: {
|
|
24
|
+
mode: 'generate',
|
|
25
|
+
grouping: 'frame',
|
|
26
|
+
format: 'google-doc',
|
|
27
|
+
register: { columns: ['Date', 'Department', 'Summary', 'Report link'] },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'files',
|
|
33
|
+
name: 'Gather files / evidence',
|
|
34
|
+
icon: '▦',
|
|
35
|
+
tagline: 'Collect photos & documents into one organized folder, with a short summary.',
|
|
36
|
+
config: {
|
|
37
|
+
description: '',
|
|
38
|
+
checklist: [
|
|
39
|
+
{ label: 'Files or photos', evidence: 'file', required: true },
|
|
40
|
+
{ label: 'A short note about them', evidence: 'text', required: false },
|
|
41
|
+
],
|
|
42
|
+
output: { mode: 'generate', grouping: 'lane' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: 'survey',
|
|
47
|
+
name: 'Survey / intake form',
|
|
48
|
+
icon: '≡',
|
|
49
|
+
tagline: 'Ask a set of questions. One tidy record per response.',
|
|
50
|
+
config: {
|
|
51
|
+
description: '',
|
|
52
|
+
checklist: [
|
|
53
|
+
{ label: 'Question 1', evidence: 'text', required: true },
|
|
54
|
+
{ label: 'Question 2', evidence: 'text', required: true },
|
|
55
|
+
{ label: 'Question 3', evidence: 'text', required: false },
|
|
56
|
+
],
|
|
57
|
+
output: { mode: 'generate', grouping: 'frame' },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
key: 'blank',
|
|
62
|
+
name: 'Blank (advanced)',
|
|
63
|
+
icon: '+',
|
|
64
|
+
tagline: 'Start from raw settings — full control.',
|
|
65
|
+
config: null,
|
|
66
|
+
},
|
|
67
|
+
];
|