| Employee | Dept | Score | Active | Idle (in shift) | Resp. progress | Late | Misuse |
|---|
Last 15 days
Delivery
Last 15 days — daily breakdown
| Day | Score | Active | Productive | Meetings | Personal | Idle (in shift) | Misuse |
|---|
Today's tldv meetings
Customers (OMS)
| Customer | Role | Status | Customer lead |
|---|
Today's top apps
| App | Active | Idle | Total | Bucket | Tag |
|---|
Today's top domains
| Domain | Active | Idle | Total | Bucket | Tag |
|---|
Today's top window titles
Visible for any non-idle activity, useful for seeing which pages/documents an employee opened when the URL itself couldn't be captured.
| Started | Window title | Time |
|---|
Responsibilities
| Title | Priority | Status | Progress | Due |
|---|
Org chart
Reporting hierarchy. Click ▸ to expand a manager's direct reports; click a name to open their detail tab. Default expansion is 2 levels — your last expand/collapse state is remembered per-browser. Filters dim non-matching nodes (the tree shape stays so you can still navigate around).
Unassigned — click to expand
Active employees with no manager set. Assign them on Manage → Employees to bring them into the tree.
Schedule vs productivity
Compares actual productive time against the
expected time defined by each employee's shift. Ratio is
weighted (uses the bucket weights from Manage → Bucket weights),
so e.g. learning time partially counts. Holidays / weekends /
admin-marked exempt days have expected = 0 and don't
drag the average down.
| Name | Department | Score | Productive | Other | Personal | Idle | After-hours | Meetings | Late | Expected |
|---|
Best & worst — last 7 days
Score = (productive + 0.5×learning − personal) ÷ active time, mapped to 0–100. Excludes employees with under 10 minutes of activity in the window. Security-risk time is shown separately as alerts — not deducted.
Auto-groups — last 14 days
Rule-based, transparent. Each membership shows the reason — useful for defending decisions in 1:1s.
Needs review
Apps, domains, and browser titles that have accumulated active time but aren't classified into a bucket yet. Tag them here once and they apply retroactively to every employee.
Uncategorized domains
Browser visits where the domain is known but no rule matches. Pick a bucket → re-classifies all matching events.
| Domain | Active time | Events | People | Tag as |
|---|
Uncategorized apps
Desktop apps with no rule match.
| App | Active time | Events | People | Tag as |
|---|
Browser titles with no domain extracted
Pages we couldn't auto-recognise. Click a title's Add keyword
button to have the title-extractor recognise that site in future
events. Choose a 2–3 word substring that's distinctive (e.g.
HRMS Login) and a target domain.
| Window title | Active time | Events | Suggest domain & tag |
|---|
OMS customers
Customers mirrored from the OMS Implementation Report. Assignments shown are currently active (excluding history). Empty until OMS pushes data via the webhook configured on Manage → Integrations.
| Customer | Status | Started | Co-ordinator | Project Leader | Customer Lead | Meetings |
|---|
tldv meetings
Each tldv-recorded meeting with its company participants and all action items extracted. Most-recent first.
tldv action items
Action items that tldv extracted from recorded meetings, awaiting admin review. Approve to create a Responsibility for the assigned employee, or dismiss if not actionable.
| Meeting | Action item | Owner | Suggested employee | Due | Status |
|---|
Monthly assessments
Rate each of your direct reports 1–5 for the month, with optional comment. Feeds the manager component (15%) of the composite score. Submit by the 5th of the next month for cleanest data — late submissions still count, but holders may have already seen draft rankings.
| Employee | Department | Role | Rating | Comment (optional) | Last saved |
|---|
Ratings: 1 below expectations · 2 needs improvement · 3 meets expectations · 4 exceeds · 5 exceptional
Monthly ranking
Composite employee score combining productivity (30%), delivery (25%), and four other components that will fill in as subsequent phases ship (manager assessment 15%, customer outcomes 15%, peer nominations 10%, tldv follow-through 5%). Components with no data are skipped — the score re-normalises over the available ones.
| # | Employee | Department | Final | Prod | Deliv | Outc | tldv | Mgr | Peer |
|---|
Positions
Job profiles per role. Every employee sees their role's profile on My Data. Empty entries (unfilled) show roles with employees but no profile written yet — click Edit to author one.
| Role | Holders | Summary | Updated |
|---|
My data
Your own activity at a glance.
Your role
Account
Sets a new password and signs out all your other sessions.
Export
Includes: activity events, daily summaries, and any RDS sessions linked to your account.
System health
Audit log
Every privileged action — grants, revokes, role changes, category re-tags, OMS syncs, retention runs.
| Time (UTC) | Actor | Action | Target | IP | Detail |
|---|
Integrations
Test the alert pipeline
Fires a synthetic alert through every configured webhook and (if SMTP is set) emails admins. Use this to verify your integrations after editing them.
Webhooks (alert push)
Each new alert is POSTed as JSON to every active matching webhook. Use this to fan out into Slack, Teams, or your ticketing system.
| Name | URL | Severity | Last fired | Last status |
|---|
Per-role bucket weights
Multiplier on the base bucket weight for a specific role. e.g. "Developer + productive × 1.5" makes IDE-time count more on the leaderboard for devs. Default = 1.0.
| Role | Bucket | × |
|---|
tldv (meeting AI assistant)
Pulls action items from tldv-recorded meetings into a review queue. Approved items become Responsibilities for the matched employee. Set the webhook URL below in your tldv workspace (Settings → Integrations → Webhooks):
/v1/tldv/webhook
OMS (Office Management System)
Mirrors the OMS Implementation Report (customer assignments) into Lakshya so each employee detail page shows the customers they're co-ordinator/project-leader for. OMS pushes via webhook on customer change. Set this URL in OMS:
/v1/oms/webhook
tldv — email coverage
Which employees has tldv seen? For each active non-role employee:
meetings matched via email (invitee list) and via
speaker (transcript). Suggested email = what tldv has them as
when their employees.email is empty or different.
Fix the email on Manage → Employees → that row to improve future
attendee resolution.
| Name | Code | Dept | Current email | Suggested (from tldv) | Matched by email | Matched by speaker |
|---|
Data retention
Delete activity_events older than N days. Daily summaries are kept indefinitely.
Agent self-update
Server's current published version is shown below.
/v1/agent/download serves the bundled exe.
Responsibilities & delivery
| Employee | Title | Pri | Status | Progress | Due | Late? |
|---|
Alerts
—| Employee | Kind | Severity | Last 14 days | Latest | State |
|---|
Attendance
—Leave applications
Approved leaves here drive the Attendance matrix: a day shows L only when a leave row covers it. Without a leave on file, a no-activity day shows A.Add leave application
| Employee | From | To | Days | Type | Reason | Status | Entered by |
|---|
Leave types
The dropdown on the Leaves page reads this list. Add a new type here (e.g. Paternity, Bereavement) and it appears in the form immediately. Deactivate a type to hide it from new entries without losing the historical leaves that used it.
Add new type
| Code | Name | Paid | Sort order | Status |
|---|
Reassign activity
Move all activity events from one employee to another for a date range. Useful when someone covered for a colleague on their machine. Preview first — the move overwrites the attribution and is logged to audit trail, but original employee_id is NOT preserved per-event.
Active RDS thin-client sessions (Windows 2012)
Maps server\session_id -> AD user -> employee record.
| Server | Session | AD User | Client name | Client IP | Mapped employee | Started |
|---|
Employees — Windows login mapping
The OMS Windows login column is what your OMS reports
(LOWER(sec_users.login)). The Override column is a
manual mapping — useful when an employee's actual Windows account name
doesn't match the OMS login (e.g. administrator,
service.user). Override wins during agent matching and
survives OMS re-syncs.
| Name | Code | Dept | Role | Office | Device | OMS Windows login | Override | Shift | Manager | Status | Monitor | Type | Dashboard access |
|---|
Windows agent — build, bundle & deploy
Build the EXE + bundle it into a single self-contained
Install-Lakshya.ps1 on a Windows box (once). Copy that
one file to each target machine. The agent reports back to
….
🚀 Ready-to-deploy installer (recommended)
One file. ~11 MB. Has the agent EXE embedded inside it. Just copy
to a Windows machine and run as Administrator with
-ServerUrl. No build step required on the target.
How to upload a fresh build (admin)
After building Install-Lakshya.ps1
on a Windows box (via build_windows.ps1 + bundle_installer.ps1),
upload it here so other admins can download it directly. In PowerShell on the build box:
$cookie = (Invoke-WebRequest "https://lakshya.pcs-india.com/v1/auth/login" -Method POST ` -Body (@{username='YOUR_ADMIN_USER'; password='YOUR_PASSWORD'} | ConvertTo-Json) ` -ContentType "application/json" -SessionVariable s).BaseResponse Invoke-WebRequest "https://lakshya.pcs-india.com/v1/admin/install-bundle" ` -Method PUT ` -InFile "C:\empmonitor\agent\Install-Lakshya.ps1" ` -ContentType "application/octet-stream" ` -WebSession $s
Once that finishes, refresh this page — the direct-download link above will appear and every admin can grab the latest installer from the dashboard.
One-click bundle (for building from source)
If you don't yet have Install-Lakshya.ps1, this zip
contains the source code + build scripts. Extract on a Windows box
with Python 3.10+ and run build_windows.ps1 then
bundle_installer.ps1 to produce
Install-Lakshya.ps1.
empmonitor_agent_bundle.zip
Or download files individually
| File | Size | Purpose |
|---|
Two ways to install on a client machine
Both produce the same any-user logon scheduled task, ACL-locked binary, Defender exclusion, and 5-min restart safety net.
① Single-file installer (recommended; works offline)
Run bundle_installer.ps1 on a Windows build
box to produce Install-Lakshya.ps1 (~16 MB, EXE embedded
inside). Copy that one file to the target. In
elevated PowerShell:
.\Install-Lakshya.ps1 -ServerUrl "…"
For roaming laptops outside the office, pass the public URL
instead:
-ServerUrl "https://lakshya.pcs-india.com".
To remove: .\Install-Lakshya.ps1 -Uninstall.
② One-line network install (target must reach this server)
Open PowerShell as Administrator on the target machine and paste:
irm …/install.ps1 | iex
Pulls the agent binary from this server, installs it, registers the same any-user scheduled task — all in one round-trip. Best when the target has network access to the server during install.
Build the agent EXE + bundle the installer (one-time, on a Windows build box)
# On any Windows machine with Python 3.10+ in PATH: Set-ExecutionPolicy -Scope Process Bypass .\agent\build_windows.ps1 # produces dist\empmonitor_agent.exe (~12 MB) .\agent\bundle_installer.ps1 # produces agent\Install-Lakshya.ps1 (~16 MB) # Then upload empmonitor_agent.exe to this server (so the one-liner above # can serve it) via PUT /v1/admin/agent-binary, and ship Install-Lakshya.ps1 # to each target.
📘 Step-by-step admin guide — installing the agent on a laptop / desktop (click to expand/collapse)
For every new Windows machine you want to monitor, follow this guide top to bottom. The whole process takes about 5 minutes per machine once you have the installer file.
⚙️ Prerequisites (one-time setup, done once company-wide)
- The installer file —
Install-Lakshya.ps1(about 11 MB). Built once from this server's bundle, then re-used on every new machine. If you don't have it yet, download empmonitor_agent_bundle.zip from the top of this page, extract on a Windows box with Python 3.10+, and run the build commands shown above. - Admin rights on the target machine
- Network access from the target machine to
https://lakshya.pcs-india.com
🚚 Step 1 — Copy the installer file to the target machine
Move Install-Lakshya.ps1 to C:\Temp\ on the target machine.
Use whatever transfer method works best:
- OneDrive / Google Drive — upload from the build machine, download on target (most reliable)
- USB stick — copy across physically
- WhatsApp Web / messaging — only works on small office networks; can mangle large files
- Email — most providers reject ~11 MB attachments; use a cloud link instead
If C:\Temp\ doesn't exist, create it: File Explorer → This PC → Local Disk (C:) →
right-click → New → Folder → name it Temp.
🔐 Step 2 — Open Administrator PowerShell on the target
- Press Win + X
- Click Terminal (Admin) or Windows PowerShell (Admin)
- Click Yes on the UAC popup
- Confirm the title bar starts with "Administrator:"
🛠️ Step 3 — Run install commands
Type each command and press Enter, one at a time. Wait for one to finish before the next.
3a. Go to the installer folder:
cd C:\Temp
3b. Allow script execution in this window only:
Set-ExecutionPolicy -Scope Process Bypass
3c. Whitelist with Windows Defender (do this BEFORE installing — Defender otherwise quarantines the EXE):
Add-MpPreference -ExclusionPath C:\ProgramData\EmpMonitor Add-MpPreference -ExclusionProcess empmonitor_agent.exe
3d. Run the installer — pick the URL based on the machine's location:
For laptops / desktops outside the office:
.\Install-Lakshya.ps1 -ServerUrl "https://lakshya.pcs-india.com"
For desktops on the office LAN (Mumbai, Udupi):
.\Install-Lakshya.ps1 -ServerUrl "http://192.168.0.131:8090"
Wait for green text ending in Installed.
🔍 Step 4 — Get the Windows username (you'll need this in Step 6)
whoami
Output looks like desktop-abc123\dell. Write down the part AFTER the backslash —
that's the Windows username (e.g. dell). Not the hostname.
✓ Step 5 — Verify the agent is alive
Confirm the agent process is running:
Get-Process empmonitor_agent | Select Id, SessionId, UserName
You should see one row with your username.
Verify the agent has the correct server URL (replace <user> with the Windows username from Step 4):
Get-Content C:\Users\<user>\.empmonitor.json
You must see "server_url": "https://lakshya.pcs-india.com"
(or the internal URL you used). If it shows http://127.0.0.1:8088
or anything else wrong, see the troubleshooting section below.
Check the log for successful registration:
Get-Content C:\Users\<user>\AppData\Local\empmonitor\agent.log -Tail 10
Look for: [agent] registered: {'agent_id': N, ...} with a real integer agent_id.
👤 Step 6 — Map the Windows user to a Lakshya employee
⚠️ This is the step that's most often missed. The agent reports the Windows username but Lakshya needs to know which employee record it belongs to.
- Open Manage → Agents and confirm the new machine appears (hostname matches, "Last seen" shows a few seconds ago).
- Open Manage → Employees and find the person who uses the new machine.
- In the AD override column (the editable text input — placeholder shows
(none)), type the Windows username from Step 4 — just the user name, NOT the hostname.
Example: typedell, notDELL2. The hostname (machine name) is what shows in Manage → Agents; the user name is what we match against. - Confirm the Monitored checkbox in the same row is ticked.
- Click Save on that row. A "saved" toast appears.
✅ Step 7 — Confirm data is flowing
Wait 1–2 minutes after Step 6, then:
- Manage → Agents — the new machine's row should show the employee's name in the "Bound to" column.
- Open that employee's detail page (click their name anywhere) — should show today's apps / domains / window titles flowing in within 2 minutes.
🩹 Troubleshooting common issues
Agent shows up in Manage → Agents but no events appear
This is the #1 cause and was the very issue solved when DELL2 went live. The agent is reaching the server fine, but events get dropped because no employee record matches the Windows username.
Fix: revisit Step 6. Make sure the AD override field on the
employee record is set to the Windows username (the part after the backslash in
whoami's output), not the hostname.
Agent log shows WinError 10061
The agent saved a wrong server URL on first start (usually the fallback
http://127.0.0.1:8088). Fix:
Get-Process empmonitor_agent | Stop-Process -Force Remove-Item C:\Users\<user>\.empmonitor.json -Force Start-ScheduledTask -TaskName "EmpMonitor Agent (system-wide)"
Wait 30 seconds, then re-check the log. The agent regenerates the config
from the EMPMON_SERVER machine env var.
Install fails with EXE does NOT start with 'MZ'
The Install-Lakshya.ps1 file got corrupted in transit. This happens
most commonly when transferred via email or some messaging apps that re-encode
attachments. Fix: re-transfer using OneDrive, Google Drive, or USB.
Verify the file size is around 11 MB.
"This script must run as Administrator"
You opened a regular PowerShell, not an admin one. Close it, then revisit Step 2 (Win+X → "Terminal (Admin)"). The title bar must start with "Administrator:".
No agent process after install / agent crashes on start
Usually antivirus quarantining. Re-run Step 3c (Defender exclusions) and then:
Start-ScheduledTask -TaskName "EmpMonitor Agent (system-wide)"
If the laptop has a third-party AV (Symantec, McAfee, Kaspersky, etc.), whitelist
C:\ProgramData\EmpMonitor\empmonitor_agent.exe in that tool too —
Defender's exclusion only covers Microsoft Defender.
If the user just installed and hasn't logged out yet, have them log out and log back in — the agent auto-starts at logon.
🗑️ To uninstall later
cd C:\Temp .\Install-Lakshya.ps1 -Uninstall
Removes the scheduled task, the binary, and the Defender exclusion. Historical data in Lakshya is preserved.
📋 Quick reference — where things live on a target machine
| Concept | Path / Name |
|---|---|
| Agent binary | C:\ProgramData\EmpMonitor\empmonitor_agent.exe |
| Per-user config (URL, agent UUID) | C:\Users\<user>\.empmonitor.json |
| Per-user log | C:\Users\<user>\AppData\Local\empmonitor\agent.log |
| Scheduled task name | EmpMonitor Agent (system-wide) |
| Server URL env var | EMPMON_SERVER (Machine scope) |
📌 The mapping rule (the one that bites everyone)
| What it is | Where you see it | Used for matching? |
|---|---|---|
Hostname (e.g. DELL2, LAPTOP-XYZ) |
Manage → Agents (the machine name) | No — informational only |
Windows username (e.g. dell, manish) |
whoami on the target (part after \) |
Yes — paste this into Employee's AD override field |
Installed agents
Every machine running an agent registers a unique
agent_key on first start. Once the key is bound to an
employee, that binding is locked — events from that key are only
attributed to that employee. To swap a stolen or stale install,
revoke the row here and reinstall on the host.
| Last seen | Hostname | OS | Version | Bound to | Key |
|---|
Category rules
| Kind | Pattern | Category | Score |
|---|
Shifts
Recurring time windows that define expected on-the-clock hours. Each employee inherits the default shift unless overridden on the Employees page. Productivity ratios on the Schedule dashboard use these windows.
Each shift now belongs to an office (or company-wide if blank), and has an effective from date. When computing for an employee on a given day, the system picks the most-recent active shift for their office whose effective_from ≤ that day, falling back to the company-wide shift if none.
| Name | Office | Effective from | Start | End | Lunch | Days | Break | TZ | Default | Status |
|---|
Holidays
Days where expected_s is forced to 0 — so
the productivity ratio reads as "off-day" rather than 0%. Leave
Office blank for company-wide holidays; otherwise it must
match the Employee.office string (e.g. Udupi).
| Date | Office | Name |
|---|
Title keywords
Maps a substring in a browser-window title to its
canonical domain. Used by the title extractor to recognise sites
like "Stack Overflow - Where Developers ..." →
stackoverflow.com. Higher priority is checked first;
keep more-specific keywords above generic ones.
| Keyword | Target domain | Priority | Active |
|---|
Office settings
Per-office effective_date — the date from
which monitoring is "live" in that location. Days before this date
are excluded from expected_s and from auto-leave for
employees in that office. Offices with no row here use the
global default on the System settings page.
| Office | Effective date | Status |
|---|
Add a new office
Use this only for offices not yet on any employee record. Otherwise the office is auto-listed above.
System settings
Configuration that affects how the productivity ratio is computed across the company.
Flagging thresholds
Two independent rules. Each can fire on its own — an employee can be flagged for unproductive use, for excess idle, or for both. Changes take effect on the next recompute (overnight, or run a manual recompute from Health).
How this is calculated
Each activity_event from the agent has a duration
(typically 5 s) and a bucket (productive / learning /
communication / neutral / personal / security_risk) plus an
idle bit. The recompute aggregates these per employee per
day:
productive_s— Σ duration where productivity > 0 (productive bucket).unproductive_s— Σ duration where productivity < 0 (default: personal bucket; weights are admin-editable).neutral_s— Σ duration where productivity = 0.idle_s— Σ duration where the idle bit is set (no keyboard/mouse activity for the agent's idle window).active_s= productive + unproductive + neutral (idle is excluded).
Unproductive flag fires when both:
active_s ≥ min_active_minutes × 60
AND unproductive_s / active_s ≥ unproductive_ratio.
Idle flag fires when
idle_s / 3600 ≥ idle_excess_hours.
The two flags are independent. The legacy combined
misuse_flag is recomputed as
unproductive_flag OR idle_flag and kept around for
backward compatibility with older queries.
Security policy
Hardening controls. Changes take effect immediately on the next request — no restart needed.
Password requirements
Applied to every password change and reset. Existing passwords stay valid until the next change unless maximum age below forces rotation.
Sessions
Account lockout
Webhook destinations
Comma-separated allow-list of hostnames. Empty = any
URL accepted (insecure on a public deploy — webhook URLs become an
SSRF surface). Set to e.g. hooks.slack.com,n8n.example.com
to restrict.
Bucket weights
Weights applied to every second of activity time when
computing the daily productivity score. Negative weights deduct
(e.g. personal). Typical range is -1.0 to
+1.0; nothing rejects values outside that range — pick
what makes sense for your formula.