@questionbase/deskfree 0.4.7 → 0.5.0
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/dist/bin.js +548 -209
- package/dist/bin.js.map +1 -1
- package/dist/cli/install.js +32 -5
- package/dist/cli/install.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +231 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/install.js
CHANGED
|
@@ -93,18 +93,36 @@ Service ${PLIST_LABEL} installed and started.`);
|
|
|
93
93
|
}
|
|
94
94
|
var SYSTEMD_SERVICE_FILE = `/etc/systemd/system/${SERVICE_NAME}.service`;
|
|
95
95
|
var SYSTEMD_ENV_FILE = `/etc/${SERVICE_NAME}.env`;
|
|
96
|
+
var LINUX_STATE_DIR = "/var/lib/deskfree-agent";
|
|
97
|
+
var LINUX_LOG_DIR = "/var/log/deskfree-agent";
|
|
96
98
|
function installLinux(token) {
|
|
97
99
|
if (process.getuid?.() !== 0) {
|
|
98
100
|
console.error("Error: install must be run as root (use sudo)");
|
|
99
101
|
process.exit(1);
|
|
100
102
|
}
|
|
101
|
-
let
|
|
103
|
+
let npmPath;
|
|
104
|
+
let nodeBinDir;
|
|
102
105
|
try {
|
|
103
|
-
|
|
106
|
+
npmPath = execSync("which npm", { encoding: "utf8" }).trim();
|
|
107
|
+
nodeBinDir = dirname(npmPath);
|
|
104
108
|
} catch {
|
|
105
|
-
console.error("Error:
|
|
109
|
+
console.error("Error: npm not found in PATH");
|
|
106
110
|
process.exit(1);
|
|
107
111
|
}
|
|
112
|
+
try {
|
|
113
|
+
execSync("id deskfree-agent", { stdio: "ignore" });
|
|
114
|
+
} catch {
|
|
115
|
+
execSync(
|
|
116
|
+
"useradd --system --no-create-home --shell /usr/sbin/nologin deskfree-agent"
|
|
117
|
+
);
|
|
118
|
+
console.log("Created system user: deskfree-agent");
|
|
119
|
+
}
|
|
120
|
+
mkdirSync(LINUX_STATE_DIR, { recursive: true });
|
|
121
|
+
mkdirSync(LINUX_LOG_DIR, { recursive: true });
|
|
122
|
+
execSync(
|
|
123
|
+
`chown deskfree-agent:deskfree-agent ${LINUX_STATE_DIR} ${LINUX_LOG_DIR}`
|
|
124
|
+
);
|
|
125
|
+
console.log(`Created ${LINUX_STATE_DIR} and ${LINUX_LOG_DIR}`);
|
|
108
126
|
writeFileSync(SYSTEMD_ENV_FILE, `DESKFREE_LAUNCH=${token}
|
|
109
127
|
`, {
|
|
110
128
|
mode: 384
|
|
@@ -118,12 +136,20 @@ Wants=network-online.target
|
|
|
118
136
|
|
|
119
137
|
[Service]
|
|
120
138
|
Type=simple
|
|
121
|
-
|
|
122
|
-
|
|
139
|
+
User=deskfree-agent
|
|
140
|
+
Group=deskfree-agent
|
|
141
|
+
WorkingDirectory=${LINUX_STATE_DIR}
|
|
142
|
+
Environment=PATH=${nodeBinDir}:/usr/local/bin:/usr/bin:/bin
|
|
143
|
+
ExecStartPre=+${npmPath} install -g ${PACKAGE}
|
|
144
|
+
ExecStart=${nodeBinDir}/deskfree-agent start
|
|
123
145
|
EnvironmentFile=${SYSTEMD_ENV_FILE}
|
|
124
146
|
Environment=NODE_ENV=production
|
|
147
|
+
Environment=DESKFREE_STATE_DIR=${LINUX_STATE_DIR}
|
|
148
|
+
Environment=DESKFREE_TOOLS_DIR=${LINUX_STATE_DIR}/tools
|
|
125
149
|
Restart=always
|
|
126
150
|
RestartSec=10
|
|
151
|
+
StandardOutput=append:${LINUX_LOG_DIR}/stdout.log
|
|
152
|
+
StandardError=append:${LINUX_LOG_DIR}/stderr.log
|
|
127
153
|
|
|
128
154
|
[Install]
|
|
129
155
|
WantedBy=multi-user.target
|
|
@@ -136,6 +162,7 @@ WantedBy=multi-user.target
|
|
|
136
162
|
console.log(`
|
|
137
163
|
Service ${SERVICE_NAME} installed and started.`);
|
|
138
164
|
console.log(`Check status: systemctl status ${SERVICE_NAME}`);
|
|
165
|
+
console.log(`Logs: tail -f ${LINUX_LOG_DIR}/stdout.log`);
|
|
139
166
|
}
|
|
140
167
|
function install(token) {
|
|
141
168
|
if (process.platform === "darwin") {
|
package/dist/cli/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/install.ts"],"names":[],"mappings":"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","file":"install.js","sourcesContent":["import { execSync } from 'node:child_process';\nimport { chmodSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst SERVICE_NAME = 'deskfree-agent';\nconst PACKAGE = '@questionbase/deskfree@latest';\n\n// ── macOS (launchd) ─────────────────────────────────────────────────────────\n\nconst PLIST_LABEL = 'com.deskfree.agent';\n\nfunction getMacPaths() {\n const home = homedir();\n const deskfreeDir = join(home, '.deskfree');\n return {\n deskfreeDir,\n envFile: join(deskfreeDir, '.env'),\n launcher: join(deskfreeDir, 'launcher.sh'),\n logDir: join(deskfreeDir, 'logs'),\n plist: join(home, 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`),\n };\n}\n\nfunction installMac(token: string): void {\n const paths = getMacPaths();\n\n // Resolve full path to node's bin directory (survives nvm/fnm across sessions)\n let nodeBinDir: string;\n try {\n const nodePath = execSync('which node', { encoding: 'utf8' }).trim();\n nodeBinDir = dirname(nodePath);\n } catch {\n console.error('Error: node not found in PATH');\n process.exit(1);\n }\n\n // Create directories\n mkdirSync(paths.deskfreeDir, { recursive: true });\n mkdirSync(paths.logDir, { recursive: true });\n mkdirSync(dirname(paths.plist), { recursive: true });\n\n // Write env file (chmod 600)\n writeFileSync(paths.envFile, `DESKFREE_LAUNCH=${token}\\n`, { mode: 0o600 });\n chmodSync(paths.envFile, 0o600);\n console.log(`Wrote ${paths.envFile}`);\n\n // Write launcher script\n const launcher = `#!/bin/bash\nset -euo pipefail\n\nexport PATH=\"${nodeBinDir}:$PATH\"\n\n# Update to latest version before starting\nnpm install -g ${PACKAGE} 2>/dev/null || true\n\n# Source env\nset -a\nsource \"${paths.envFile}\"\nset +a\n\nexec deskfree-agent start\n`;\n\n writeFileSync(paths.launcher, launcher, { mode: 0o755 });\n chmodSync(paths.launcher, 0o755);\n console.log(`Wrote ${paths.launcher}`);\n\n // Write LaunchAgent plist\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${PLIST_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${paths.launcher}</string>\n </array>\n <key>KeepAlive</key>\n <true/>\n <key>RunAtLoad</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${join(paths.logDir, 'stdout.log')}</string>\n <key>StandardErrorPath</key>\n <string>${join(paths.logDir, 'stderr.log')}</string>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n</dict>\n</plist>\n`;\n\n writeFileSync(paths.plist, plist);\n console.log(`Wrote ${paths.plist}`);\n\n // Unload if already loaded (ignore errors)\n try {\n execSync(`launchctl bootout gui/$(id -u) ${paths.plist}`, {\n stdio: 'ignore',\n });\n } catch {\n // not loaded — fine\n }\n\n // Load the service\n execSync(`launchctl bootstrap gui/$(id -u) ${paths.plist}`);\n\n console.log(`\\nService ${PLIST_LABEL} installed and started.`);\n console.log(`Check status: launchctl print gui/$(id -u)/${PLIST_LABEL}`);\n console.log(`Logs: tail -f ${join(paths.logDir, 'stdout.log')}`);\n}\n\n// ── Linux (systemd) ─────────────────────────────────────────────────────────\n\nconst SYSTEMD_SERVICE_FILE = `/etc/systemd/system/${SERVICE_NAME}.service`;\nconst SYSTEMD_ENV_FILE = `/etc/${SERVICE_NAME}.env`;\n\nfunction installLinux(token: string): void {\n if (process.getuid?.() !== 0) {\n console.error('Error: install must be run as root (use sudo)');\n process.exit(1);\n }\n\n // Resolve full npx path so systemd doesn't depend on PATH\n let npxPath: string;\n try {\n npxPath = execSync('which npx', { encoding: 'utf8' }).trim();\n } catch {\n console.error('Error: npx not found in PATH');\n process.exit(1);\n }\n\n // Write env file with token (chmod 600 — only root can read)\n writeFileSync(SYSTEMD_ENV_FILE, `DESKFREE_LAUNCH=${token}\\n`, {\n mode: 0o600,\n });\n chmodSync(SYSTEMD_ENV_FILE, 0o600);\n console.log(`Wrote ${SYSTEMD_ENV_FILE}`);\n\n // Write systemd unit file\n const unit = `[Unit]\nDescription=DeskFree Agent\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nExecStartPre=${npxPath} ${PACKAGE} --version\nExecStart=${npxPath} ${PACKAGE} start\nEnvironmentFile=${SYSTEMD_ENV_FILE}\nEnvironment=NODE_ENV=production\nRestart=always\nRestartSec=10\n\n[Install]\nWantedBy=multi-user.target\n`;\n\n writeFileSync(SYSTEMD_SERVICE_FILE, unit);\n console.log(`Wrote ${SYSTEMD_SERVICE_FILE}`);\n\n // Enable and start\n execSync('systemctl daemon-reload');\n execSync(`systemctl enable ${SERVICE_NAME}`);\n execSync(`systemctl start ${SERVICE_NAME}`);\n\n console.log(`\\nService ${SERVICE_NAME} installed and started.`);\n console.log(`Check status: systemctl status ${SERVICE_NAME}`);\n}\n\n// ── Public API ──────────────────────────────────────────────────────────────\n\nexport function install(token: string): void {\n if (process.platform === 'darwin') {\n installMac(token);\n } else if (process.platform === 'linux') {\n installLinux(token);\n } else {\n console.error(`Unsupported platform: ${process.platform}`);\n process.exit(1);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/install.ts"],"names":[],"mappings":"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","file":"install.js","sourcesContent":["import { execSync } from 'node:child_process';\nimport { chmodSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nconst SERVICE_NAME = 'deskfree-agent';\nconst PACKAGE = '@questionbase/deskfree@latest';\n\n// ── macOS (launchd) ─────────────────────────────────────────────────────────\n\nconst PLIST_LABEL = 'com.deskfree.agent';\n\nfunction getMacPaths() {\n const home = homedir();\n const deskfreeDir = join(home, '.deskfree');\n return {\n deskfreeDir,\n envFile: join(deskfreeDir, '.env'),\n launcher: join(deskfreeDir, 'launcher.sh'),\n logDir: join(deskfreeDir, 'logs'),\n plist: join(home, 'Library', 'LaunchAgents', `${PLIST_LABEL}.plist`),\n };\n}\n\nfunction installMac(token: string): void {\n const paths = getMacPaths();\n\n // Resolve full path to node's bin directory (survives nvm/fnm across sessions)\n let nodeBinDir: string;\n try {\n const nodePath = execSync('which node', { encoding: 'utf8' }).trim();\n nodeBinDir = dirname(nodePath);\n } catch {\n console.error('Error: node not found in PATH');\n process.exit(1);\n }\n\n // Create directories\n mkdirSync(paths.deskfreeDir, { recursive: true });\n mkdirSync(paths.logDir, { recursive: true });\n mkdirSync(dirname(paths.plist), { recursive: true });\n\n // Write env file (chmod 600)\n writeFileSync(paths.envFile, `DESKFREE_LAUNCH=${token}\\n`, { mode: 0o600 });\n chmodSync(paths.envFile, 0o600);\n console.log(`Wrote ${paths.envFile}`);\n\n // Write launcher script\n const launcher = `#!/bin/bash\nset -euo pipefail\n\nexport PATH=\"${nodeBinDir}:$PATH\"\n\n# Update to latest version before starting\nnpm install -g ${PACKAGE} 2>/dev/null || true\n\n# Source env\nset -a\nsource \"${paths.envFile}\"\nset +a\n\nexec deskfree-agent start\n`;\n\n writeFileSync(paths.launcher, launcher, { mode: 0o755 });\n chmodSync(paths.launcher, 0o755);\n console.log(`Wrote ${paths.launcher}`);\n\n // Write LaunchAgent plist\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${PLIST_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${paths.launcher}</string>\n </array>\n <key>KeepAlive</key>\n <true/>\n <key>RunAtLoad</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${join(paths.logDir, 'stdout.log')}</string>\n <key>StandardErrorPath</key>\n <string>${join(paths.logDir, 'stderr.log')}</string>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n</dict>\n</plist>\n`;\n\n writeFileSync(paths.plist, plist);\n console.log(`Wrote ${paths.plist}`);\n\n // Unload if already loaded (ignore errors)\n try {\n execSync(`launchctl bootout gui/$(id -u) ${paths.plist}`, {\n stdio: 'ignore',\n });\n } catch {\n // not loaded — fine\n }\n\n // Load the service\n execSync(`launchctl bootstrap gui/$(id -u) ${paths.plist}`);\n\n console.log(`\\nService ${PLIST_LABEL} installed and started.`);\n console.log(`Check status: launchctl print gui/$(id -u)/${PLIST_LABEL}`);\n console.log(`Logs: tail -f ${join(paths.logDir, 'stdout.log')}`);\n}\n\n// ── Linux (systemd) ─────────────────────────────────────────────────────────\n\nconst SYSTEMD_SERVICE_FILE = `/etc/systemd/system/${SERVICE_NAME}.service`;\nconst SYSTEMD_ENV_FILE = `/etc/${SERVICE_NAME}.env`;\n\nconst LINUX_STATE_DIR = '/var/lib/deskfree-agent';\nconst LINUX_LOG_DIR = '/var/log/deskfree-agent';\n\nfunction installLinux(token: string): void {\n if (process.getuid?.() !== 0) {\n console.error('Error: install must be run as root (use sudo)');\n process.exit(1);\n }\n\n // Resolve full npm/node bin dir so systemd doesn't depend on PATH\n let npmPath: string;\n let nodeBinDir: string;\n try {\n npmPath = execSync('which npm', { encoding: 'utf8' }).trim();\n nodeBinDir = dirname(npmPath);\n } catch {\n console.error('Error: npm not found in PATH');\n process.exit(1);\n }\n\n // Create dedicated system user (no login shell, no home dir)\n try {\n execSync('id deskfree-agent', { stdio: 'ignore' });\n } catch {\n execSync(\n 'useradd --system --no-create-home --shell /usr/sbin/nologin deskfree-agent',\n );\n console.log('Created system user: deskfree-agent');\n }\n\n // Create state and log directories owned by the service user\n mkdirSync(LINUX_STATE_DIR, { recursive: true });\n mkdirSync(LINUX_LOG_DIR, { recursive: true });\n execSync(\n `chown deskfree-agent:deskfree-agent ${LINUX_STATE_DIR} ${LINUX_LOG_DIR}`,\n );\n console.log(`Created ${LINUX_STATE_DIR} and ${LINUX_LOG_DIR}`);\n\n // Write env file with token (chmod 600 — only root can read)\n writeFileSync(SYSTEMD_ENV_FILE, `DESKFREE_LAUNCH=${token}\\n`, {\n mode: 0o600,\n });\n chmodSync(SYSTEMD_ENV_FILE, 0o600);\n console.log(`Wrote ${SYSTEMD_ENV_FILE}`);\n\n // Write systemd unit file\n // ExecStartPre updates to latest version before each start (same as macOS launcher)\n const unit = `[Unit]\nDescription=DeskFree Agent\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nUser=deskfree-agent\nGroup=deskfree-agent\nWorkingDirectory=${LINUX_STATE_DIR}\nEnvironment=PATH=${nodeBinDir}:/usr/local/bin:/usr/bin:/bin\nExecStartPre=+${npmPath} install -g ${PACKAGE}\nExecStart=${nodeBinDir}/deskfree-agent start\nEnvironmentFile=${SYSTEMD_ENV_FILE}\nEnvironment=NODE_ENV=production\nEnvironment=DESKFREE_STATE_DIR=${LINUX_STATE_DIR}\nEnvironment=DESKFREE_TOOLS_DIR=${LINUX_STATE_DIR}/tools\nRestart=always\nRestartSec=10\nStandardOutput=append:${LINUX_LOG_DIR}/stdout.log\nStandardError=append:${LINUX_LOG_DIR}/stderr.log\n\n[Install]\nWantedBy=multi-user.target\n`;\n\n writeFileSync(SYSTEMD_SERVICE_FILE, unit);\n console.log(`Wrote ${SYSTEMD_SERVICE_FILE}`);\n\n // Enable and start\n execSync('systemctl daemon-reload');\n execSync(`systemctl enable ${SERVICE_NAME}`);\n execSync(`systemctl start ${SERVICE_NAME}`);\n\n console.log(`\\nService ${SERVICE_NAME} installed and started.`);\n console.log(`Check status: systemctl status ${SERVICE_NAME}`);\n console.log(`Logs: tail -f ${LINUX_LOG_DIR}/stdout.log`);\n}\n\n// ── Public API ──────────────────────────────────────────────────────────────\n\nexport function install(token: string): void {\n if (process.platform === 'darwin') {\n installMac(token);\n } else if (process.platform === 'linux') {\n installLinux(token);\n } else {\n console.error(`Unsupported platform: ${process.platform}`);\n process.exit(1);\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PluginLogger, DeskFreeClient, DeskFreeTool, ChatMessage, RuntimeBootstrapConfig } from '@deskfree/core';
|
|
1
|
+
import { PluginLogger, AgentContext, DeskFreeClient, DeskFreeTool, ChatMessage, RuntimeBootstrapConfig } from '@deskfree/core';
|
|
2
2
|
import * as _anthropic_ai_claude_agent_sdk from '@anthropic-ai/claude-agent-sdk';
|
|
3
3
|
import { McpSdkServerConfigWithInstance, SDKMessage, SDKUserMessage, Query, tool } from '@anthropic-ai/claude-agent-sdk';
|
|
4
4
|
|
|
@@ -28,6 +28,8 @@ interface OrchestratorQueryOptions {
|
|
|
28
28
|
sessionId?: string;
|
|
29
29
|
/** Path to user's Claude Code executable (uses bundled CLI if omitted). */
|
|
30
30
|
claudeCodePath?: string;
|
|
31
|
+
/** Runtime context for templated system prompt. Falls back to static directive if omitted. */
|
|
32
|
+
agentContext?: AgentContext;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Run the orchestrator agent. Returns an async iterable of SDKMessage events.
|
|
@@ -44,6 +46,8 @@ interface HeartbeatOptions {
|
|
|
44
46
|
model: string;
|
|
45
47
|
/** Path to user's Claude Code executable (uses bundled CLI if omitted). */
|
|
46
48
|
claudeCodePath?: string;
|
|
49
|
+
/** Runtime context for templated system prompt. Falls back to static directive if omitted. */
|
|
50
|
+
agentContext?: AgentContext;
|
|
47
51
|
}
|
|
48
52
|
/**
|
|
49
53
|
* Run a one-shot heartbeat query (no session persistence).
|
|
@@ -56,6 +60,8 @@ interface WorkerQueryOptions {
|
|
|
56
60
|
model: string;
|
|
57
61
|
/** Agent SDK session ID to resume (for multi-turn task conversations). */
|
|
58
62
|
sessionId?: string;
|
|
63
|
+
/** Runtime context for templated system prompt. Falls back to static directive if omitted. */
|
|
64
|
+
agentContext?: AgentContext;
|
|
59
65
|
}
|
|
60
66
|
/**
|
|
61
67
|
* Run the worker agent directly. Returns a Query (async iterable of
|
|
@@ -111,6 +117,8 @@ interface WorkerManagerDeps {
|
|
|
111
117
|
dailyLogCharBudget?: number;
|
|
112
118
|
/** Path to persist session history JSON (taskId → sessionId). */
|
|
113
119
|
sessionHistoryPath?: string;
|
|
120
|
+
/** Runtime context for templated system prompts. */
|
|
121
|
+
agentContext?: AgentContext;
|
|
114
122
|
}
|
|
115
123
|
declare class WorkerManager {
|
|
116
124
|
private workers;
|
|
@@ -386,6 +394,10 @@ interface RuntimeConfig extends LocalConfig {
|
|
|
386
394
|
baseUrl?: string;
|
|
387
395
|
/** Bot ID for this runtime instance */
|
|
388
396
|
botId: string;
|
|
397
|
+
/** Bot's display name (e.g. "Sofia") */
|
|
398
|
+
botName: string;
|
|
399
|
+
/** Deployment type (aws, docker, local) */
|
|
400
|
+
deploymentType: 'aws' | 'docker' | 'local' | null;
|
|
389
401
|
/** File ID for the bot's Memory file (null if not created yet) */
|
|
390
402
|
memoryFileId: string | null;
|
|
391
403
|
/** Hour of day (0-23) in local time for the nightly sleep cycle (null = disabled) */
|