@causyne/agent 0.0.0-stage → 1.10.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/LICENSE +102 -0
- package/README.md +31 -2
- package/SECURITY.md +24 -0
- package/bin/causyne.js +13 -0
- package/docs/ARCHITECTURE.md +63 -0
- package/docs/PROVENANCE.md +29 -0
- package/docs/SECURITY_REVIEW.md +89 -0
- package/docs/THIRD_PARTY_NOTICES.md +49 -0
- package/native-skills/ai-engineering/context-window-management/SKILL.md +43 -0
- package/native-skills/ai-engineering/llm-evaluation/SKILL.md +46 -0
- package/native-skills/ai-engineering/model-cost-and-latency/SKILL.md +46 -0
- package/native-skills/ai-engineering/prompt-construction/SKILL.md +42 -0
- package/native-skills/ai-engineering/retrieval-augmented-generation/SKILL.md +42 -0
- package/native-skills/ai-engineering/structured-output-and-schemas/SKILL.md +45 -0
- package/native-skills/ai-engineering/tool-calling-agents/SKILL.md +43 -0
- package/native-skills/android/app-performance-profiling/SKILL.md +42 -0
- package/native-skills/android/background-work-scheduling/SKILL.md +47 -0
- package/native-skills/android/compose-state-and-recomposition/SKILL.md +43 -0
- package/native-skills/android/gradle-build-configuration/SKILL.md +41 -0
- package/native-skills/android/lifecycle-and-leaks/SKILL.md +46 -0
- package/native-skills/android/play-store-release/SKILL.md +43 -0
- package/native-skills/android/room-and-persistence/SKILL.md +40 -0
- package/native-skills/backend/authentication-and-sessions/SKILL.md +45 -0
- package/native-skills/backend/background-jobs-and-queues/SKILL.md +42 -0
- package/native-skills/backend/caching-strategy/SKILL.md +44 -0
- package/native-skills/backend/graceful-shutdown/SKILL.md +42 -0
- package/native-skills/backend/rate-limiting-and-quotas/SKILL.md +40 -0
- package/native-skills/backend/rest-api-design/SKILL.md +40 -0
- package/native-skills/backend/webhook-delivery-and-receipt/SKILL.md +43 -0
- package/native-skills/cloud/cost-optimisation/SKILL.md +46 -0
- package/native-skills/cloud/iam-least-privilege/SKILL.md +43 -0
- package/native-skills/cloud/infrastructure-as-code/SKILL.md +43 -0
- package/native-skills/cloud/multi-region-and-failover/SKILL.md +43 -0
- package/native-skills/cloud/serverless-patterns/SKILL.md +47 -0
- package/native-skills/data/data-quality-monitoring/SKILL.md +51 -0
- package/native-skills/data/etl-pipeline-reliability/SKILL.md +43 -0
- package/native-skills/data/exploratory-analysis/SKILL.md +43 -0
- package/native-skills/data/metric-definition/SKILL.md +42 -0
- package/native-skills/data/notebook-to-production/SKILL.md +43 -0
- package/native-skills/database/backup-and-recovery/SKILL.md +43 -0
- package/native-skills/database/connection-pooling/SKILL.md +42 -0
- package/native-skills/database/data-integrity-and-constraints/SKILL.md +42 -0
- package/native-skills/database/query-optimisation/SKILL.md +38 -0
- package/native-skills/database/safe-migrations/SKILL.md +47 -0
- package/native-skills/database/schema-design/SKILL.md +38 -0
- package/native-skills/database/transactions-and-isolation/SKILL.md +41 -0
- package/native-skills/design/colour-system-construction/SKILL.md +38 -0
- package/native-skills/design/design-direction-brief/SKILL.md +41 -0
- package/native-skills/design/motion-and-transitions/SKILL.md +38 -0
- package/native-skills/design/responsive-strategy/SKILL.md +39 -0
- package/native-skills/design/spacing-and-rhythm/SKILL.md +38 -0
- package/native-skills/design/type-scale-and-hierarchy/SKILL.md +39 -0
- package/native-skills/design/visual-qa-loop/SKILL.md +42 -0
- package/native-skills/devops/docker-multi-stage-builds/SKILL.md +60 -0
- package/native-skills/devops/github-actions-ci/SKILL.md +60 -0
- package/native-skills/devops/incident-triage/SKILL.md +38 -0
- package/native-skills/devops/kubernetes-deployment-hardening/SKILL.md +64 -0
- package/native-skills/devops/observability-baseline/SKILL.md +38 -0
- package/native-skills/devops/secret-management/SKILL.md +40 -0
- package/native-skills/devops/terraform-state-and-modules/SKILL.md +36 -0
- package/native-skills/devops/zero-downtime-deploys/SKILL.md +40 -0
- package/native-skills/git/bisect-regression-hunt/SKILL.md +43 -0
- package/native-skills/git/branch-strategy/SKILL.md +39 -0
- package/native-skills/git/commit-hygiene/SKILL.md +41 -0
- package/native-skills/git/history-recovery/SKILL.md +44 -0
- package/native-skills/git/large-repository-surgery/SKILL.md +46 -0
- package/native-skills/git/merge-conflict-resolution/SKILL.md +42 -0
- package/native-skills/media/cinematic-3d-shot/SKILL.md +104 -0
- package/native-skills/mobile/app-startup-optimisation/SKILL.md +41 -0
- package/native-skills/mobile/cross-platform-tradeoffs/SKILL.md +42 -0
- package/native-skills/mobile/deep-linking/SKILL.md +39 -0
- package/native-skills/mobile/mobile-storage-security/SKILL.md +45 -0
- package/native-skills/mobile/offline-first-sync/SKILL.md +42 -0
- package/native-skills/mobile/push-notifications/SKILL.md +38 -0
- package/native-skills/performance/algorithmic-complexity/SKILL.md +43 -0
- package/native-skills/performance/concurrency-and-parallelism/SKILL.md +42 -0
- package/native-skills/performance/load-testing/SKILL.md +42 -0
- package/native-skills/performance/memory-and-leak-hunting/SKILL.md +41 -0
- package/native-skills/performance/network-and-payload-efficiency/SKILL.md +42 -0
- package/native-skills/performance/profiling-methodology/SKILL.md +46 -0
- package/native-skills/python/async-correctness/SKILL.md +40 -0
- package/native-skills/python/cli-tool-construction/SKILL.md +44 -0
- package/native-skills/python/data-processing-pipelines/SKILL.md +38 -0
- package/native-skills/python/environment-isolation/SKILL.md +41 -0
- package/native-skills/python/packaging-and-distribution/SKILL.md +56 -0
- package/native-skills/python/pytest-suite-design/SKILL.md +39 -0
- package/native-skills/python/type-hints-and-static-checking/SKILL.md +42 -0
- package/native-skills/security/authorization-model/SKILL.md +42 -0
- package/native-skills/security/crypto-usage/SKILL.md +48 -0
- package/native-skills/security/dependency-supply-chain/SKILL.md +42 -0
- package/native-skills/security/input-validation-and-injection/SKILL.md +44 -0
- package/native-skills/security/secure-file-uploads/SKILL.md +46 -0
- package/native-skills/security/security-headers-and-csp/SKILL.md +44 -0
- package/native-skills/security/threat-modelling/SKILL.md +46 -0
- package/native-skills/testing/end-to-end-test-stability/SKILL.md +42 -0
- package/native-skills/testing/property-based-testing/SKILL.md +46 -0
- package/native-skills/testing/regression-test-from-a-bug/SKILL.md +41 -0
- package/native-skills/testing/snapshot-and-visual-regression/SKILL.md +42 -0
- package/native-skills/testing/test-doubles-and-mocking/SKILL.md +43 -0
- package/native-skills/testing/test-strategy-and-pyramid/SKILL.md +39 -0
- package/native-skills/testing/writing-good-assertions/SKILL.md +42 -0
- package/native-skills/web/accessible-components/SKILL.md +45 -0
- package/native-skills/web/api-client-resilience/SKILL.md +39 -0
- package/native-skills/web/bundle-size-reduction/SKILL.md +38 -0
- package/native-skills/web/core-web-vitals/SKILL.md +40 -0
- package/native-skills/web/css-layout-systems/SKILL.md +41 -0
- package/native-skills/web/form-validation-ux/SKILL.md +39 -0
- package/native-skills/web/react-state-architecture/SKILL.md +41 -0
- package/native-skills/web/ssr-hydration-correctness/SKILL.md +45 -0
- package/package.json +68 -4
- package/src/agentLoop.js +2458 -0
- package/src/appChannel.js +109 -0
- package/src/approvalGrants.js +66 -0
- package/src/auditLog.js +52 -0
- package/src/autoUpdate.js +12 -0
- package/src/capabilities.js +36 -0
- package/src/checkpoints.js +1199 -0
- package/src/cliMode.js +638 -0
- package/src/commands.js +805 -0
- package/src/compiledSkills.js +540 -0
- package/src/config.js +130 -0
- package/src/contextManager.js +498 -0
- package/src/cortex/autoCondenser.js +192 -0
- package/src/cortex/provisioner.js +27 -0
- package/src/cortex/vectorDb.js +447 -0
- package/src/designPalettes.js +99 -0
- package/src/devMode.js +6 -0
- package/src/embodimentSession.js +180 -0
- package/src/entrypoint.js +194 -0
- package/src/execSafe.js +21 -0
- package/src/gitSnapshot.js +378 -0
- package/src/mcp/jsonRpc.js +165 -0
- package/src/mcp/mcpClient.js +136 -0
- package/src/mcp/mcpRegistry.js +207 -0
- package/src/memory.js +62 -0
- package/src/memoryManager.js +124 -0
- package/src/modelCatalogue.js +132 -0
- package/src/modelIds.js +42 -0
- package/src/modelRouter.js +145 -0
- package/src/outputStore.js +246 -0
- package/src/perception.js +124 -0
- package/src/planCache.js +437 -0
- package/src/procSignal.js +32 -0
- package/src/providers/anthropic.js +408 -0
- package/src/providers/base.js +328 -0
- package/src/providers/dashscope-byok.js +86 -0
- package/src/providers/deepseek.js +80 -0
- package/src/providers/factory.js +37 -0
- package/src/providers/gemini.js +346 -0
- package/src/providers/moonshot.js +73 -0
- package/src/providers/muse.js +169 -0
- package/src/providers/ollama.js +104 -0
- package/src/providers/openai-compatible.js +84 -0
- package/src/providers/openai.js +20 -0
- package/src/providers/qwen-byok.js +76 -0
- package/src/providers/xai.js +73 -0
- package/src/provisioning/capabilityConsent.js +24 -0
- package/src/provisioning/capabilityProvisioner.js +271 -0
- package/src/provisioning/capabilityTools.js +29 -0
- package/src/reporting.js +373 -0
- package/src/sandbox.js +529 -0
- package/src/sessionStore.js +279 -0
- package/src/skillsManager.js +288 -0
- package/src/slopDetector.js +307 -0
- package/src/taskBuffer.js +45 -0
- package/src/taskShape.js +241 -0
- package/src/textDiff.js +150 -0
- package/src/tokenTracker.js +560 -0
- package/src/tool-scripts/ax_snapshot.applescript +39 -0
- package/src/tool-scripts/ax_snapshot.ps1 +10 -0
- package/src/tool-scripts/desktop_act.applescript +58 -0
- package/src/tool-scripts/resolve_automator.py +119 -0
- package/src/toolPacks.js +524 -0
- package/src/tools/archive.js +63 -0
- package/src/tools/astryxOracle.js +78 -0
- package/src/tools/axSnapshot.js +165 -0
- package/src/tools/blenderAutomator.js +349 -0
- package/src/tools/browserAutomator.js +252 -0
- package/src/tools/checkSystemSpecs.js +64 -0
- package/src/tools/clipboard.js +36 -0
- package/src/tools/codeSearchAst.js +101 -0
- package/src/tools/codeSearcher.js +230 -0
- package/src/tools/codeTools.js +262 -0
- package/src/tools/codebaseSearch.js +75 -0
- package/src/tools/createSkill.js +129 -0
- package/src/tools/deferredMcpSearch.js +246 -0
- package/src/tools/desktopAct.js +208 -0
- package/src/tools/desktopOpen.js +34 -0
- package/src/tools/dynamicLoader.js +44 -0
- package/src/tools/executeProceduralMedia.js +93 -0
- package/src/tools/fsDelete.js +51 -0
- package/src/tools/fsEdit.js +105 -0
- package/src/tools/fsFind.js +128 -0
- package/src/tools/fsList.js +77 -0
- package/src/tools/fsMove.js +57 -0
- package/src/tools/fsRead.js +87 -0
- package/src/tools/fsSearch.js +198 -0
- package/src/tools/fsWrite.js +41 -0
- package/src/tools/gameAiBehaviorTree.js +208 -0
- package/src/tools/gameAnimationRig.js +194 -0
- package/src/tools/gameAssetFetcher.js +372 -0
- package/src/tools/gameAssetHarvester.js +210 -0
- package/src/tools/gameAudioSynth.js +267 -0
- package/src/tools/gameBuilder.js +886 -0
- package/src/tools/gameCanvasAudit.js +101 -0
- package/src/tools/gameCinematicSequencer.js +151 -0
- package/src/tools/gameDataForge.js +124 -0
- package/src/tools/gameDialogueTreeGen.js +166 -0
- package/src/tools/gameEconomyBalancer.js +161 -0
- package/src/tools/gameEntitySpawner.js +207 -0
- package/src/tools/gameLoreForge.js +153 -0
- package/src/tools/gameQuestArcBuilder.js +152 -0
- package/src/tools/gameSceneBuilder.js +158 -0
- package/src/tools/gameShaderForge.js +181 -0
- package/src/tools/gameTilemapGenerator.js +164 -0
- package/src/tools/gameUiHudBuilder.js +292 -0
- package/src/tools/gameVfxEmitterGen.js +108 -0
- package/src/tools/gameWebRuntimeInspector.js +91 -0
- package/src/tools/generateMediaViaApi.js +358 -0
- package/src/tools/gitExec.js +54 -0
- package/src/tools/godotAutomator.js +437 -0
- package/src/tools/manageLocalAiDependencies.js +220 -0
- package/src/tools/memoryWrite.js +99 -0
- package/src/tools/multiEdit.js +107 -0
- package/src/tools/palmierAutomator.js +104 -0
- package/src/tools/pdfReader.js +112 -0
- package/src/tools/persistentShell.js +148 -0
- package/src/tools/printer.js +316 -0
- package/src/tools/procTerm.js +91 -0
- package/src/tools/processList.js +52 -0
- package/src/tools/readNativeSkill.js +39 -0
- package/src/tools/registry.js +277 -0
- package/src/tools/resolveAutomator.js +102 -0
- package/src/tools/screenshot.js +75 -0
- package/src/tools/subagentOrchestrator.js +305 -0
- package/src/tools/sysRun.js +125 -0
- package/src/tools/todoWrite.js +75 -0
- package/src/tools/toolDispatch.js +127 -0
- package/src/tools/toolForge.js +124 -0
- package/src/tools/updatePlan.js +88 -0
- package/src/tools/viewImage.js +82 -0
- package/src/tools/visionInspector.js +154 -0
- package/src/tools/webFetch.js +74 -0
- package/src/tools/webSearch.js +82 -0
- package/src/tui/ask.js +164 -0
- package/src/tui/banner.js +158 -0
- package/src/tui/block.js +152 -0
- package/src/tui/chatRenderer.js +953 -0
- package/src/tui/completion.js +424 -0
- package/src/tui/dialogs.js +606 -0
- package/src/tui/diff.js +296 -0
- package/src/tui/history.js +135 -0
- package/src/tui/home.js +217 -0
- package/src/tui/invocation.js +105 -0
- package/src/tui/keys.js +443 -0
- package/src/tui/lineEditor.js +256 -0
- package/src/tui/overlay.js +256 -0
- package/src/tui/prompt.js +1258 -0
- package/src/tui/selectList.js +335 -0
- package/src/tui/stage.js +330 -0
- package/src/tui/stageSurface.js +609 -0
- package/src/tui/statusLine.js +254 -0
- package/src/tui/text.js +345 -0
- package/src/tui/theme.js +393 -0
- package/src/tui/toolDisplay.js +176 -0
- package/src/tui/transcript.js +235 -0
- package/src/tui/viewport.js +337 -0
- package/src/uncertainty.js +271 -0
- package/src/userSkills.js +265 -0
- package/src/utils/cli_ui.js +0 -0
- package/src/utils/inquirer.js +12 -0
- package/src/utils/paths.js +37 -0
- package/src/version.js +38 -0
- package/src/vfeTracker.js +220 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CAUSYNE AGENT - Sovereign Universal Print Engine (`printer.js`)
|
|
3
|
+
* AGI-Level Physical & Virtual Printer Control across Windows, macOS, and Linux.
|
|
4
|
+
*
|
|
5
|
+
* SECURITY & ARCHITECTURE GUARANTEES:
|
|
6
|
+
* 1. Zero Shell Injection (`execFile` with argument array directly to OS kernel `execve`).
|
|
7
|
+
* 2. Zero Human Touch (`Start-Process -WindowStyle Hidden / Out-Printer / lp`).
|
|
8
|
+
* 3. Comprehensive Situational Awareness (`printer.list_printers`, `printer.get_status`).
|
|
9
|
+
*/
|
|
10
|
+
import { execFile } from 'child_process';
|
|
11
|
+
import util from 'util';
|
|
12
|
+
import os from 'os';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import fs from 'fs';
|
|
15
|
+
|
|
16
|
+
const execFileAsync = util.promisify(execFile);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ── TOOL 1: printer.print (`printer_print`) ──
|
|
20
|
+
* Sends a document (PDF, TXT, Word, Image) directly to physical hardware with zero human touch.
|
|
21
|
+
*/
|
|
22
|
+
export const printerPrint = {
|
|
23
|
+
schema: {
|
|
24
|
+
name: 'printer.print',
|
|
25
|
+
description: 'Sends a document (PDF, TXT, Word, Image) directly to physical or virtual printers on the host OS with zero human touch or GUI pop-up.',
|
|
26
|
+
parameters: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: {
|
|
29
|
+
filePath: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: 'Absolute path to the document or image to be printed.',
|
|
32
|
+
},
|
|
33
|
+
printerName: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Optional name of the target physical printer. If omitted, sends to the OS default physical printer.',
|
|
36
|
+
},
|
|
37
|
+
copies: {
|
|
38
|
+
type: 'integer',
|
|
39
|
+
description: 'Number of copies to print (default: 1).',
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
required: ['filePath'],
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
execute: async (args, context) => {
|
|
46
|
+
try {
|
|
47
|
+
const { filePath, printerName, copies = 1 } = args;
|
|
48
|
+
const resolvedPath = path.resolve(filePath);
|
|
49
|
+
|
|
50
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: `Document not found at path: ${resolvedPath}`
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const platform = os.platform();
|
|
58
|
+
|
|
59
|
+
if (platform === 'darwin' || platform === 'linux') {
|
|
60
|
+
// Unix CUPS: Use direct execFile array to prevent shell injection ($(), ``, ;, &&)
|
|
61
|
+
const lpArgs = [];
|
|
62
|
+
if (printerName) {
|
|
63
|
+
lpArgs.push('-d', printerName);
|
|
64
|
+
}
|
|
65
|
+
if (copies && copies > 1) {
|
|
66
|
+
lpArgs.push('-n', String(copies));
|
|
67
|
+
}
|
|
68
|
+
lpArgs.push(resolvedPath);
|
|
69
|
+
|
|
70
|
+
const { stdout, stderr } = await execFileAsync('lp', lpArgs);
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
message: `Document successfully dispatched to CUPS print spooler (${printerName || 'Default Printer'}). Zero human touch.`,
|
|
74
|
+
stdout: (stdout || '').trim(),
|
|
75
|
+
stderr: (stderr || '').trim()
|
|
76
|
+
};
|
|
77
|
+
} else if (platform === 'win32') {
|
|
78
|
+
// Windows PowerShell: Execute via execFile with -NoProfile -NonInteractive
|
|
79
|
+
const escapedPath = resolvedPath.replace(/'/g, "''");
|
|
80
|
+
const ext = path.extname(resolvedPath).toLowerCase();
|
|
81
|
+
let psScript = '';
|
|
82
|
+
|
|
83
|
+
if (['.txt', '.log', '.csv', '.json', '.md'].includes(ext)) {
|
|
84
|
+
// Direct text spooling: Get-Content -> Out-Printer (100% background, no application required)
|
|
85
|
+
const target = printerName ? ` -Name '${printerName.replace(/'/g, "''")}'` : '';
|
|
86
|
+
psScript = `1..${Math.max(1, copies)} | ForEach-Object { Get-Content -LiteralPath '${escapedPath}' | Out-Printer${target} }`;
|
|
87
|
+
} else {
|
|
88
|
+
// General documents (.pdf, .docx, .png): Shell Verb Print in hidden background window
|
|
89
|
+
// If printerName is specified, try setting default temporarily or passing via Start-Process
|
|
90
|
+
const count = Math.max(1, copies);
|
|
91
|
+
psScript = `
|
|
92
|
+
1..${count} | ForEach-Object {
|
|
93
|
+
Start-Process -FilePath '${escapedPath}' -Verb Print -WindowStyle Hidden -PassThru | Out-Null
|
|
94
|
+
}
|
|
95
|
+
`.trim();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const { stdout, stderr } = await execFileAsync('powershell.exe', [
|
|
99
|
+
'-NoProfile',
|
|
100
|
+
'-NonInteractive',
|
|
101
|
+
'-Command',
|
|
102
|
+
psScript
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
success: true,
|
|
107
|
+
message: `Document dispatched to Windows Spooler (${printerName || 'Default Printer'}) via headless zero-touch execution.`,
|
|
108
|
+
stdout: (stdout || '').trim(),
|
|
109
|
+
stderr: (stderr || '').trim()
|
|
110
|
+
};
|
|
111
|
+
} else {
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error: `Unsupported OS platform for direct physical printing: ${platform}`
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
return {
|
|
119
|
+
success: false,
|
|
120
|
+
error: `Failed to print document: ${error.message}`
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* ── TOOL 2: printer.list_printers (`printer_list_printers`) ──
|
|
128
|
+
* Discovers all connected physical and virtual printers, indicating status and default targets.
|
|
129
|
+
*/
|
|
130
|
+
export const printerList = {
|
|
131
|
+
schema: {
|
|
132
|
+
name: 'printer.list_printers',
|
|
133
|
+
description: 'Discovers all physical and virtual printers connected to the local system, returning their names, default status, and online availability.',
|
|
134
|
+
parameters: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
properties: {}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
execute: async (args, context) => {
|
|
140
|
+
try {
|
|
141
|
+
const platform = os.platform();
|
|
142
|
+
|
|
143
|
+
if (platform === 'darwin' || platform === 'linux') {
|
|
144
|
+
// Run lpstat -p -d via safe execFile
|
|
145
|
+
const { stdout } = await execFileAsync('lpstat', ['-p', '-d']).catch(e => ({ stdout: e.stdout || '' }));
|
|
146
|
+
const lines = (stdout || '').split('\n').map(l => l.trim()).filter(Boolean);
|
|
147
|
+
|
|
148
|
+
let defaultPrinter = null;
|
|
149
|
+
const printers = [];
|
|
150
|
+
|
|
151
|
+
for (const line of lines) {
|
|
152
|
+
if (line.startsWith('system default destination:')) {
|
|
153
|
+
defaultPrinter = line.split(':')[1]?.trim() || null;
|
|
154
|
+
} else if (line.startsWith('printer ')) {
|
|
155
|
+
const parts = line.split(' ');
|
|
156
|
+
const name = parts[1];
|
|
157
|
+
const isIdle = line.includes('is idle');
|
|
158
|
+
const isPrinting = line.includes('now printing');
|
|
159
|
+
const isDisabled = line.includes('disabled');
|
|
160
|
+
let status = 'Unknown';
|
|
161
|
+
if (isDisabled) status = 'Offline/Disabled';
|
|
162
|
+
else if (isPrinting) status = 'Printing';
|
|
163
|
+
else if (isIdle) status = 'Ready';
|
|
164
|
+
|
|
165
|
+
printers.push({
|
|
166
|
+
name,
|
|
167
|
+
status,
|
|
168
|
+
isDefault: name === defaultPrinter,
|
|
169
|
+
rawDescription: line
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Check if default printer marked
|
|
175
|
+
printers.forEach(p => {
|
|
176
|
+
if (p.name === defaultPrinter) p.isDefault = true;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
success: true,
|
|
181
|
+
platform,
|
|
182
|
+
defaultPrinter,
|
|
183
|
+
printersCount: printers.length,
|
|
184
|
+
printers
|
|
185
|
+
};
|
|
186
|
+
} else if (platform === 'win32') {
|
|
187
|
+
// Run PowerShell WMI query safely
|
|
188
|
+
const psScript = `
|
|
189
|
+
Get-CimInstance -ClassName Win32_Printer | Select-Object Name, Default, PrinterStatus, WorkOffline | ConvertTo-Json -Compress
|
|
190
|
+
`.trim();
|
|
191
|
+
|
|
192
|
+
const { stdout } = await execFileAsync('powershell.exe', [
|
|
193
|
+
'-NoProfile',
|
|
194
|
+
'-NonInteractive',
|
|
195
|
+
'-Command',
|
|
196
|
+
psScript
|
|
197
|
+
]);
|
|
198
|
+
|
|
199
|
+
let raw = [];
|
|
200
|
+
try {
|
|
201
|
+
const parsed = JSON.parse(stdout.trim() || '[]');
|
|
202
|
+
raw = Array.isArray(parsed) ? parsed : [parsed];
|
|
203
|
+
} catch (e) {
|
|
204
|
+
raw = [];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const statusMap = {
|
|
208
|
+
1: 'Other', 2: 'Unknown', 3: 'Ready', 4: 'Printing', 5: 'Warming Up',
|
|
209
|
+
6: 'Stopped/Offline', 7: 'Offline'
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const printers = raw.map(p => ({
|
|
213
|
+
name: p.Name,
|
|
214
|
+
status: p.WorkOffline ? 'Offline' : (statusMap[p.PrinterStatus] || 'Ready'),
|
|
215
|
+
isDefault: Boolean(p.Default)
|
|
216
|
+
}));
|
|
217
|
+
|
|
218
|
+
const defaultPrinter = printers.find(p => p.isDefault)?.name || null;
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
success: true,
|
|
222
|
+
platform,
|
|
223
|
+
defaultPrinter,
|
|
224
|
+
printersCount: printers.length,
|
|
225
|
+
printers
|
|
226
|
+
};
|
|
227
|
+
} else {
|
|
228
|
+
return { success: false, error: `Unsupported OS platform: ${platform}` };
|
|
229
|
+
}
|
|
230
|
+
} catch (error) {
|
|
231
|
+
return { success: false, error: `Failed to list printers: ${error.message}` };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* ── TOOL 3: printer.get_status (`printer_get_status`) ──
|
|
238
|
+
* Inspects active print jobs and queue health across physical hardware.
|
|
239
|
+
*/
|
|
240
|
+
export const printerStatus = {
|
|
241
|
+
schema: {
|
|
242
|
+
name: 'printer.get_status',
|
|
243
|
+
description: 'Inspects active print jobs and queue health on all connected physical or virtual printers.',
|
|
244
|
+
parameters: {
|
|
245
|
+
type: 'object',
|
|
246
|
+
properties: {
|
|
247
|
+
printerName: {
|
|
248
|
+
type: 'string',
|
|
249
|
+
description: 'Optional printer name to filter queue status.'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
execute: async (args, context) => {
|
|
255
|
+
try {
|
|
256
|
+
const { printerName } = args || {};
|
|
257
|
+
const platform = os.platform();
|
|
258
|
+
|
|
259
|
+
if (platform === 'darwin' || platform === 'linux') {
|
|
260
|
+
const lpArgs = printerName ? ['-o', printerName] : ['-o'];
|
|
261
|
+
const { stdout } = await execFileAsync('lpstat', lpArgs).catch(e => ({ stdout: e.stdout || '' }));
|
|
262
|
+
const lines = (stdout || '').split('\n').map(l => l.trim()).filter(Boolean);
|
|
263
|
+
|
|
264
|
+
const activeJobs = lines.map(line => {
|
|
265
|
+
const parts = line.split(' ');
|
|
266
|
+
return {
|
|
267
|
+
jobId: parts[0],
|
|
268
|
+
owner: parts[1] || 'Unknown',
|
|
269
|
+
sizeOrStatus: parts.slice(2).join(' ')
|
|
270
|
+
};
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
success: true,
|
|
275
|
+
platform,
|
|
276
|
+
activeJobsCount: activeJobs.length,
|
|
277
|
+
activeJobs
|
|
278
|
+
};
|
|
279
|
+
} else if (platform === 'win32') {
|
|
280
|
+
const filter = printerName ? ` -Filter "Name LIKE '%${printerName.replace(/'/g, "''")}%'"` : '';
|
|
281
|
+
const psScript = `
|
|
282
|
+
Get-CimInstance -ClassName Win32_PrintJob${filter} | Select-Object JobId, Document, Owner, Status | ConvertTo-Json -Compress
|
|
283
|
+
`.trim();
|
|
284
|
+
|
|
285
|
+
const { stdout } = await execFileAsync('powershell.exe', [
|
|
286
|
+
'-NoProfile',
|
|
287
|
+
'-NonInteractive',
|
|
288
|
+
'-Command',
|
|
289
|
+
psScript
|
|
290
|
+
]);
|
|
291
|
+
|
|
292
|
+
let raw = [];
|
|
293
|
+
try {
|
|
294
|
+
const parsed = JSON.parse(stdout.trim() || '[]');
|
|
295
|
+
raw = Array.isArray(parsed) ? parsed : [parsed];
|
|
296
|
+
} catch (e) {
|
|
297
|
+
raw = [];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
success: true,
|
|
302
|
+
platform,
|
|
303
|
+
activeJobsCount: raw.length,
|
|
304
|
+
activeJobs: raw
|
|
305
|
+
};
|
|
306
|
+
} else {
|
|
307
|
+
return { success: false, error: `Unsupported OS platform: ${platform}` };
|
|
308
|
+
}
|
|
309
|
+
} catch (error) {
|
|
310
|
+
return { success: false, error: `Failed to inspect printer status: ${error.message}` };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// Backwards compatibility alias for registry single imports
|
|
316
|
+
export const printerTool = printerPrint;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { sendSignal } from '../procSignal.js';
|
|
2
|
+
import { ensureCapability, loadCapabilityPackage } from '../provisioning/capabilityProvisioner.js';
|
|
3
|
+
|
|
4
|
+
export const procTerm = {
|
|
5
|
+
schema: {
|
|
6
|
+
name: 'proc.term',
|
|
7
|
+
description: 'Gracefully terminate a running process via native POSIX signals without shell execution vulnerabilities.',
|
|
8
|
+
parameters: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
pid: { type: 'number' },
|
|
12
|
+
name: { type: 'string' },
|
|
13
|
+
port: { type: 'number' },
|
|
14
|
+
signal: { type: 'string', description: 'Signal name (e.g. SIGTERM, SIGKILL). Defaults to SIGTERM.' }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
async execute(args) {
|
|
19
|
+
try {
|
|
20
|
+
const signal = args.signal || 'SIGTERM';
|
|
21
|
+
let targetPids = [];
|
|
22
|
+
|
|
23
|
+
if (args.pid) {
|
|
24
|
+
targetPids.push(args.pid);
|
|
25
|
+
}
|
|
26
|
+
else if (args.name || args.port) {
|
|
27
|
+
// D-2 resolved: `find-process` was referenced but was in neither
|
|
28
|
+
// dependencies nor node_modules, so this branch had never once worked.
|
|
29
|
+
// Adding it would have meant a new static dependency (ZM-06); instead
|
|
30
|
+
// the resolution reuses systeminformation, which the "system"
|
|
31
|
+
// capability group already provisions for process_list. One package,
|
|
32
|
+
// one consent prompt, two tools.
|
|
33
|
+
const capability = await ensureCapability('system');
|
|
34
|
+
if (!capability.ok) {
|
|
35
|
+
return {
|
|
36
|
+
success: false,
|
|
37
|
+
error: capability.reason + ' Until then, pass an explicit numeric pid.',
|
|
38
|
+
requiresConsent: capability.requiresConsent
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const si = await loadCapabilityPackage('systeminformation');
|
|
42
|
+
|
|
43
|
+
let results = [];
|
|
44
|
+
if (args.name) {
|
|
45
|
+
const wanted = String(args.name).toLowerCase();
|
|
46
|
+
const data = await si.processes();
|
|
47
|
+
results = (data.list || []).filter(proc =>
|
|
48
|
+
String(proc.name || '').toLowerCase().includes(wanted) ||
|
|
49
|
+
String(proc.command || '').toLowerCase().includes(wanted)
|
|
50
|
+
);
|
|
51
|
+
} else if (args.port) {
|
|
52
|
+
// Port ownership is a separate table; map it back to the pid.
|
|
53
|
+
const connections = await si.networkConnections();
|
|
54
|
+
const wanted = String(args.port);
|
|
55
|
+
results = (connections || [])
|
|
56
|
+
.filter(conn => String(conn.localPort) === wanted && conn.pid)
|
|
57
|
+
.map(conn => ({ pid: Number(conn.pid) }));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (results.length === 0) {
|
|
61
|
+
return { success: false, error: `No matching processes found for ${args.name || 'port ' + args.port}` };
|
|
62
|
+
}
|
|
63
|
+
targetPids = [...new Set(results.map(proc => proc.pid))].filter(Number.isInteger);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return { success: false, error: 'Must provide pid, name, or port' };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Phase 6 AGI Upgrade: Graceful Native POSIX Signal Delivery
|
|
70
|
+
let killedCount = 0;
|
|
71
|
+
let failedCount = 0;
|
|
72
|
+
|
|
73
|
+
for (const pid of targetPids) {
|
|
74
|
+
try {
|
|
75
|
+
sendSignal(pid, signal);
|
|
76
|
+
killedCount++;
|
|
77
|
+
} catch (e) {
|
|
78
|
+
failedCount++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (killedCount === 0 && failedCount > 0) {
|
|
83
|
+
return { success: false, error: `Failed to deliver ${signal} to ${failedCount} processes. They may be immune or require elevated privileges.` };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return { success: true, output: `Successfully dispatched native ${signal} signal to ${killedCount} processes.` };
|
|
87
|
+
} catch (e) {
|
|
88
|
+
return { success: false, error: e.message };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ensureCapability, loadCapabilityPackage } from '../provisioning/capabilityProvisioner.js';
|
|
2
|
+
export const processList = {
|
|
3
|
+
schema: {
|
|
4
|
+
name: 'process.list',
|
|
5
|
+
description: 'List running processes using native OS bindings. Automatically filters out OS noise to protect Context Window.',
|
|
6
|
+
parameters: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
filter: { type: 'string', description: 'Filter by name (e.g. "node")' }
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
async execute(args) {
|
|
14
|
+
try {
|
|
15
|
+
// Phase 2 AGI Upgrade: Native OS Bindings
|
|
16
|
+
const capability = await ensureCapability('system');
|
|
17
|
+
if (!capability.ok) return { success: false, error: capability.reason, requiresConsent: capability.requiresConsent };
|
|
18
|
+
const si = await loadCapabilityPackage('systeminformation');
|
|
19
|
+
|
|
20
|
+
const processData = await si.processes();
|
|
21
|
+
|
|
22
|
+
let filtered = processData.list.filter(p => {
|
|
23
|
+
// AGI Optimization: Keep heavy applications (CPU > 5% or RAM > ~100MB depending on OS reporting)
|
|
24
|
+
if (p.cpu > 5 || p.mem > 1) return true;
|
|
25
|
+
|
|
26
|
+
// Keep common dev tools
|
|
27
|
+
const name = p.name.toLowerCase();
|
|
28
|
+
if (name.includes('node') || name.includes('python') || name.includes('docker') || name.includes('java') || name.includes('git')) return true;
|
|
29
|
+
|
|
30
|
+
// Keep Causyne processes
|
|
31
|
+
if (p.command && p.command.toLowerCase().includes('causyne')) return true;
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (args.filter) {
|
|
37
|
+
filtered = filtered.filter(p => p.name.toLowerCase().includes(args.filter.toLowerCase()));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const formatted = filtered.map(p => ({
|
|
41
|
+
pid: p.pid,
|
|
42
|
+
name: p.name,
|
|
43
|
+
cpu_percent: Math.round(p.cpu),
|
|
44
|
+
ram_mb: Math.round(p.memRss / 1024)
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
return { success: true, output: JSON.stringify(formatted, null, 2) };
|
|
48
|
+
} catch (e) {
|
|
49
|
+
return { success: false, error: e.message };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readCompiledSkill } from '../skillsManager.js';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
schema: {
|
|
5
|
+
name: "fs_read_skill",
|
|
6
|
+
description: "Read the full contents of a native AI skill from the bundled readable skill data. Use this to read the instructions for a specific skill.",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
skill_id: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "The ID of the skill to read (e.g. 'devops/docker-best-practices' or 'python/python-env-isolation')"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
required: ["skill_id"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
execute: async (args) => {
|
|
19
|
+
try {
|
|
20
|
+
const parts = args.skill_id.split('/');
|
|
21
|
+
if (parts.length !== 2) {
|
|
22
|
+
return { success: false, error: 'Invalid skill_id format. Expected "domain/skillName"' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const domain = parts[0];
|
|
26
|
+
const skillName = parts[1];
|
|
27
|
+
|
|
28
|
+
const content = readCompiledSkill(domain, skillName);
|
|
29
|
+
|
|
30
|
+
if (content.startsWith('Error:')) {
|
|
31
|
+
return { success: false, error: content };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return { success: true, result: content };
|
|
35
|
+
} catch (e) {
|
|
36
|
+
return { success: false, error: e.message };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|