Keyboard shortcuts

Press ? or ? to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Overview

People Work exists to help managers and their engineering teams better manage the people side of their jobs. In short it helps a manager become a better manager and an employee better engage the performance management process.

Motivation

As a technical manager, you started your career in a technical capacity with lots of tools at your disposal, the loveliest and most used of which was your IDE of choice. I’m sure you can think of 3 or 4 tools off the top of your head that you used daily. Can you imagine having done your engineering job without them?

Then you became a manager, and suddenly the landscape of tooling was abysmal. You have the HR-approved tooling that you mostly just use to approve time off and submit performance reviews with. Beyond that, you probably just use Word or Google Docs to keep track of 1:1 notes for each of your direct reports. They’re such big files that you rarely go back and read anything because it’s really hard to find. Then when review time rolls around, you fall prey to the bias of the present. You talk about their last couple of projects and can’t remember anything that happened more than 6 weeks ago.

What if you had an IDE for managing your team? Just like during your technical days, you had an IDE to help you with best practices, like unit testing, builds, compiling, etc. What if you had an IDE to help you with 1:1s, reviews, feedback, and other performance related things? Think of how much more successful of a manager you would be for your team if you had a world-class tool helping you rather than a tool for someone else that makes you feel like you’re just checking off a box.

And what if this tool was so good that your technical team actually used it to engage in their own career growth, resulting in them being more engaged and more productive team members? Those types of teams and leaders are rare. We build the tooling to create those outcomes and make your journey as manager as short and upwardly mobile as possible.

You may think of this as a typically HR tool, and you're right - it is! But we are here to partner with HR in order to enable managers and employees to do better at managing relationships in order for HR to manage more strategic outcomes.

Installation

System Requirements

  • Operating System: macOS 15 or newer
  • Memory Usage: People Work app is expected to use about 70-80 MB of RAM, which is quite efficient and shouldn't impact system performance.

Installation Options

Early Access Program

People Work is currently in Early Access!

To join our Early Access Program and receive installation instructions, please sign up using this form.

macOS Configuration

If you want to navigate our forms via the keyboard through tabbing, you should configure your System Settings:

  1. Open up System Settings on your Mac
  2. Search for "Mission Control" and click on "Keyboard and Mouse Shortcuts" on the left
  3. In the "Keyboard Navigation" section on the right, click on "Keyboard Shortcuts"
  4. Ensure the "Keyboard Navigation" tab is on

system settings

Workspaces

Workspaces are the fundamental grouping, or tenant, used in the app. A workspace is located within a folder that fits a very specific structure outlined in the dsl section below.

You can use a workspace in any way you like, but we recommend keeping it simple and doing one for work and perhaps one for your professional network outside of work.

When sharing a workspace, the following items are shared:

  • Assets such as avatar images
  • Members (but not the users' contacts)
  • Career Matrices + Jobs
  • Company Values (coming soon)

Onboarding

When you first open the People Work app, you will see a screen like this:

onboarding screen

If you have a shared workspace from another member of your organization, then you will click "Open Existing Workspace..." and navigate to that workspace.

If you are creating a new workspace, then you will see a form to create a new workspace when you click on "Create New Workspace...". Here is an example of a filled out form:

create a new workspace

Once you save, you will see an empty workspace with only your user in it along with some onboarding tasks.

new workspace with tasks

These tasks will guide you through adding contacts to each relationship group. Click on the Segment button in order to add contacts to the selected group.

segmenting tasks

Add your contacts and select "Add another after save" if you wish to add more than one to that group.

add contacts to relationship group

For each contact that you add, you will see a new task to create a plan for that person.

create plan for contact

Once you add all of the contacts that you wish to add via the UI or the contact in the DSL, you will see all of your contacts in your workspace like so:

populated workspace

You're now ready to start using the app!

DSL Overview

This section outlines our custom domain specific language for the application.

Motivation

We started developing these features in a much more conventional way, as a web application connected to a SQL database. As we used the app, we felt something was missing:

  1. Ownership - For true growth to happen, we know that honesty and vulnerability are key, two things that we feel strongly about enabling in our app. We wanted our users to feel safe to share about their private goals and sensitive work relationships in our app, and in order to better facilitate that, we wanted to let our users own their own data, not for it to be in the cloud where someone else had control over it.
  2. Visibility - We wanted the user to know exactly what the app was storing, no hidden data that they couldn't control.
  3. Insights - We want AI to be able to easily read and comment on the data but in a way that the user can control.

This DSL is our answer to those problems. It enables a private, locally stored database that is human readable and, with a bit of training, human writable.

Once onboarded, a user can choose to only interact with their workspace through the desktop application, however, the DSL will remain at the core.

Workspaces

At the core of our DSL is a workspace, which is a logical group of people that the user can relate to. Most people will have a workspace for their place of employment. But other people may choose to track their professional relationships outside of work and in other areas as well.

Workspace Structure

Workspaces are structured by convention:

  1. ./workspace.toml contains the name of the workspace and the schema version of the DSL.
  2. ./core.ppl contains the core, shareable concepts that make up the workspace, like members, jobs, and matrices. This is meant to be shareable with others in that same organization, to help them get started faster.
  3. ./people.ppl contains the user-specific connection to the core. Here declares themselves as the user and determines who their contacts are.They also set an intention for how to connect with each.
  4. ./work this is where the user tracks their work for themselves and each of their contacts. This is in the form of journaling connections
  5. ./assets this is where files are stored that the workspace relates to.

Console App

We provide the people command line application in order to help you work with a workspace without having to open the full app. There are two commands to use:

people init

Will set up a new workspace.

people check

Will ensure that a workspace is valid.

This tool is self documenting so run:

people

To learn about all the options.

Visual Studio Code Extension

We also provide a Visual Studio Code Extension for this DSL, which provides syntax highlighting.

Core

The core is stored in ./core.ppl. It is the part of the workspace that could easily be shared with other people in their organization, therefore it does not contain any private or user-specific data in it. The core consists of members, jobs, and matrices.

Member

A member is a part of the core and stored in ./core.ppl of the workspace. It tracks the basic and widely available information for a person or employee within an organization. A member also has an avatar which is stored by their id.

Fields

  • first_name - (Required) The first name of the person - String
  • last_name - (Required) The last name of the person - String
  • job - (Optional) The identifier of the job the person has, in order track their performance or as an optional reference. - Identifier
  • email - (Optional) The person's email - String

Examples

Minimal

member alex_rivera {
  first_name: "Alex"
  last_name: "Rivera"
}

Full

// avatar stored at ./assets/avatars/tara_johnson.jpg
member tara_johnson {
  first_name: "Tara"
  last_name: "Johnson"
  email: "tara@somecorp.com"
  job: principal_software_engineer
}

Job

A job is a part of the core and stored in ./core.ppl of the workspace. It tracks the basic requirements for a position within an organization, primarily for performance management purposes. It also defines requirements within the career matrix.

Fields

The following arguments are supported:

  • name - (Required) The human-readable name of the job - String
  • requirements - (Optional) A map of requirements by category for this job. See the career matrix topic for a full description. This field's properties are dependent on what is defined there.

Examples

Minimal

// since there are no requirements, there should be no career matrix either.
job manager {
  name: "Engineering Manager"
}

member alex_rivera {
  first_name: "Alex"
  last_name: "Rivera"
  job: manager
}

Full

job software_engineer_1 {
  name: "Software Engineer I"
  requirements: {
    technical: {
      implementation: "Implements well-defined features with guidance"
      code_quality: "Writes maintainable code following team standards"
      code_review: "Participates in code reviews and bug fixes"
      testing: "Learns testing best practices"
    }
    project_execution: {
      delivery: "Delivers assigned tasks within expected timeframes"
      clarity: "Seeks clarification when requirements are unclear"
      updates: "Updates progress regularly"
      process: "Follows established development processes"
    }
    problem_solving: {
      debugging: "Debugs and resolves basic technical issues"
      impact: "Understands how their code impacts immediate dependencies"
      decomposition: "Learns to break down problems into manageable tasks"
    }
    collaboration: {
      participation: "Actively participates in team meetings"
      communication: "Communicates blockers and progress clearly"
      feedback: "Receives and implements feedback effectively"
      teamwork: "Works well with immediate team members"
    }
    growth: {
      learning: "Demonstrates eagerness to learn new technologies"
      initiative: "Takes initiative in skill development"
      mentorship: "Seeks and accepts mentorship"
      domain: "Builds understanding of product domain"
    }
  }
}

matrix software_engineering {
  name: "Software Engineering"
  categories: {
    technical: {
      name: "Technical"
      description: "Core technical and architectural capabilities"
    }
    project_execution: {
      name: "Project Execution"
      description: "Delivery and implementation of technical work"
    }
    problem_solving: {
      name: "Problem Solving"
      description: "Technical problem solving and system thinking"
    }
    collaboration: {
      name: "Collaboration"
      description: "Working with others and leadership"
    }
    growth: {
      name: "Growth and Learning"
      description: "Personal and professional development"
    }
  }
  jobs: [
    software_engineer_1,
  ]
}

member kevin_osei {
  first_name: "Kevin"
  last_name: "Osei"
  job: software_engineer_1
}

Matrix

A career matrix is a part of the core and stored in ./core.ppl of the workspace. It tracks the structure of requirements for a family of jobs in order to create clear career progression.

Fields

  • name - (Required) - The human-readable name of the matrix - String
  • categories - (Required) - A map of categories (detailed below) mapped by their category identifier, which is also used by the job requirments configuration
  • jobs - (Required) - A list of job identifiers that are a part of the career matrix. - [Identifier]

A category block is defined within the categories block. It defines a single category of job requirements for each job in this matrix. It is identified by a unique identifier within the matrix that is used to define the job requirements. Each category has its own block.

  • name - A human readable name of the category - String
  • description - A human readable description of the types of requirements in this category - String

Categories and Job Requirements

Career matrices and jobs have a structural relationship with each other when defined together.

The matrix defines categories, and the identifier of each category (technical in the minimal example below) is also defined as a requirement for the job.

If this structure isn't exactly right, the workspace will fail to load, so someone configuring a matrix with jobs should make good use of the people app.

Examples

Minimal

matrix engineering {
  name: "Software Engineering"
  categories: {
    technical: {
      name: "Technical"
      description: "Core technical and architectural capabilities"
    }
  }
  jobs: [
    software_engineer_1,
  ]
}

job software_engineer_1 {
  name: "Software Engineer I"
  requirements: {
    technical: {
      implementation: "Implements well-defined features with guidance"
    }
  }
}

member kevin_osei {
  first_name: "Kevin"
  last_name: "Osei"
  job: software_engineer_1
}

Full

job software_engineer_1 {
  name: "Software Engineer I"
  requirements: {
    technical: {
      implementation: "Implements well-defined features with guidance"
      code_quality: "Writes maintainable code following team standards"
      code_review: "Participates in code reviews and bug fixes"
      testing: "Learns testing best practices"
    }
    project_execution: {
      delivery: "Delivers assigned tasks within expected timeframes"
      clarity: "Seeks clarification when requirements are unclear"
      updates: "Updates progress regularly"
      process: "Follows established development processes"
    }
    problem_solving: {
      debugging: "Debugs and resolves basic technical issues"
      impact: "Understands how their code impacts immediate dependencies"
      decomposition: "Learns to break down problems into manageable tasks"
    }
    collaboration: {
      participation: "Actively participates in team meetings"
      communication: "Communicates blockers and progress clearly"
      feedback: "Receives and implements feedback effectively"
      teamwork: "Works well with immediate team members"
    }
    growth: {
      learning: "Demonstrates eagerness to learn new technologies"
      initiative: "Takes initiative in skill development"
      mentorship: "Seeks and accepts mentorship"
      domain: "Builds understanding of product domain"
    }
  }
}

job software_engineer_2 {
  name: "Software Engineer II"
  requirements: {
    technical: {
      implementation: "Independently implements medium-sized features"
      design: "Designs straightforward technical solutions"
      code_review: "Provides thorough code reviews"
      documentation: "Contributes to technical documentation"
    }
    project_execution: {
      delivery: "Manages own deliverables reliably"
      decision_making: "Makes informed technical decisions"
      estimation: "Estimates work effort accurately"
      risk_management: "Identifies potential risks early"
    }
    problem_solving: {
      resolution: "Resolves complex issues independently"
      system_thinking: "Considers broader system impact"
      improvement: "Suggests process improvements"
      optimization: "Identifies optimization opportunities"
    }
    collaboration: {
      mentoring: "Mentors junior engineers informally"
      cross_team: "Communicates effectively across teams"
      technical_discussion: "Contributes constructively to technical discussions"
      status: "Provides clear status updates"
    }
    growth: {
      technical_growth: "Expands technical breadth"
      domain_expertise: "Develops domain expertise"
      feedback: "Proactively seeks feedback"
      strategy: "Understands product strategy"
    }
  }
}

job senior_engineer {
  name: "Senior Software Engineer"
  requirements: {
    technical: {
      implementation: "Designs and implements complex features"
      architecture: "Architects scalable solutions"
      leadership: "Provides technical leadership"
      best_practices: "Drives best practices adoption"
    }
    project_execution: {
      initiative: "Leads significant technical initiatives"
      technical_debt: "Balances technical debt with delivery"
      architecture: "Makes sound architectural decisions"
      quality: "Ensures quality of deliverables"
    }
    problem_solving: {
      challenges: "Solves ambiguous technical challenges"
      scaling: "Anticipates scaling problems"
      solutions: "Creates systemic solutions"
      processes: "Improves development processes"
    }
    collaboration: {
      mentoring: "Mentors other engineers actively"
      influence: "Influences technical decisions"
      leadership: "Drives technical discussions"
      cross_org: "Works effectively across organization"
    }
    growth: {
      leadership: "Develops leadership capabilities"
      perspective: "Broadens system perspective"
      industry: "Stays current with industry trends"
      vision: "Contributes to technical vision"
    }
  }
}

job staff_engineer {
  name: "Staff Software Engineer"
  requirements: {
    technical: {
      architecture: "Architects complex distributed systems"
      strategy: "Drives technical strategy across projects"
      oversight: "Provides technical oversight for critical initiatives"
      decisions: "Makes high-impact architectural decisions"
    }
    project_execution: {
      leadership: "Leads multi-team technical initiatives"
      roadmap: "Defines technical roadmaps"
      excellence: "Ensures technical excellence across projects"
      balance: "Balances business needs with technical concerns"
    }
    problem_solving: {
      challenges: "Solves organizational technical challenges"
      architecture: "Creates scalable system architectures"
      opportunities: "Identifies strategic technical opportunities"
      governance: "Develops technical governance"
    }
    collaboration: {
      influence: "Influences cross-team technical decisions"
      consensus: "Builds consensus across engineering groups"
      mentoring: "Mentors senior engineers"
      communication: "Communicates technical vision effectively"
    }
    growth: {
      innovation: "Drives technical innovation"
      culture: "Shapes engineering culture"
      industry: "Contributes to industry discussions"
      leadership: "Develops organizational leadership skills"
    }
  }
}

job principal_engineer {
  name: "Principal Software Engineer"
  requirements: {
    technical: {
      vision: "Defines technical vision for multiple products"
      strategy: "Creates multi-year technical strategies"
      innovation: "Drives innovation in core architectures"
      standards: "Establishes technical standards"
    }
    project_execution: {
      leadership: "Leads organization-wide technical initiatives"
      planning: "Drives strategic technical planning"
      impact: "Makes decisions affecting multiple teams"
      strategy: "Influences product strategy"
    }
    problem_solving: {
      challenges: "Solves complex organizational challenges"
      capabilities: "Creates new technical capabilities"
      opportunities: "Identifies strategic opportunities"
      practices: "Develops engineering best practices"
    }
    collaboration: {
      influence: "Influences organization direction"
      partnerships: "Builds strategic partnerships"
      mentoring: "Mentors technical leaders"
      representation: "Represents engineering organization"
    }
    growth: {
      practice: "Advances state of practice"
      knowledge: "Contributes to industry knowledge"
      leadership: "Develops future technical leaders"
      culture: "Shapes engineering culture"
    }
  }
}

matrix software_engineering {
  name: "Software Engineering"
  categories: {
    technical: {
      name: "Technical"
      description: "Core technical and architectural capabilities"
    }
    project_execution: {
      name: "Project Execution"
      description: "Delivery and implementation of technical work"
    }
    problem_solving: {
      name: "Problem Solving"
      description: "Technical problem solving and system thinking"
    }
    collaboration: {
      name: "Collaboration"
      description: "Working with others and leadership"
    }
    growth: {
      name: "Growth and Learning"
      description: "Personal and professional development"
    }
  }
  jobs: [
    software_engineer_1,
    software_engineer_2,
    senior_engineer,
    staff_engineer,
    principal_engineer
  ]
}

member kevin_osei {
  first_name: "Kevin"
  last_name: "Osei"
  job: software_engineer_2
  email: "test-kevin-osei@hedge-ops.com"
}

member alex_rivera {
  first_name: "Alex"
  last_name: "Rivera"
  email: "test-alex-rivera@hedge-ops.com"
}

People

The people section of the DSL is stored in ./people.ppl and stores the user-specific data for the app. It is not meant to be shared among people in the organization.

In this app, the user defines which member they are via user declaration and which members they want to relate to as contacts.

User

Located in ./people.ppl, this is the member associated with the user. It is associated by sharing the same id.

This exists so that the core can be shared and the user can still relate themselves to that core.

If a user is not defined, the workspace will not load.

Fields

None

Examples

member alex_rivera {
  first_name: "Alex"
  last_name: "Rivera"
}

// same id as alex_rivera member, which means that Alex is
// the first person of this workspace (aka the user).
// no fields defined so no braces required
user alex_rivera {}

Contact

Located in ./people.ppl, this is the member that the user relates with in order to achieve their goals within the organization. The contact is associated with the member by sharing the same id.

This exists so the core can be shared, different users can relate to different people.

Fields

  • relationship - (Required) What type of relationship this contact is. Choices include stakeholder, peer, team, and community - Identifier

Groups

This app is prescriptive in helping people identify important relationships within an organization and the primary actions they will take with each. For that reason, the user will categorize their contacts into 4 different groups defined by the primary action they will focus on with each:

  1. Align: These are stakeholders the user needs to align with in order to succeed. These people have a vested interest in the user's delivery. They will therefore advocate for user when they are not in the room.
  2. Partner: These are peers, usually the people who report to the user's boss, sharing in a broader mission than the user has. This team is important to track because in order to perform and grow, one has to be supportive and not competitive with their peers.
  3. Guide: These make up the user's team, people who either report to the user or who look to the user for guidance, mentorship, or leadership when an individual contributor. The user likely has a vested interest in the outcome of their work.
  4. Network: this is every other important relationship that comprises the user's community, meant to ensure that there is a wider impact than just the team.

Examples

Minimal

member kevin_osei {
  first_name: "Kevin"
  last_name: "Osei"
}

// same id as kevin_osei member, which means that Kevin is
// a person the user of this workspace is relating to.
contact kevin_osei {
  group: guide
}

Full

member jordan_kim {
  first_name: "Jordan"
  last_name: "Kim"
}

contact jordan_kim {
  group: guide
}

Work

The policy of the app is set up with the core and people apps, but now it's time to do the work!

Types of Work

File Format

Each unit of work is defined within a file with a .wrk extension, straightforward and extensible. The file's name is the id for that work.

Connections - Journaling

As the user connects with themselves or other contacts, they will journal those connections. This is located in ./work/[id]/connections where [id] is the identifier of the user or contact.

File Format

The file is saved as [YYYY-mm-dd]_[event_name_identifier].wrk where the first part is the date of the connection and the second part is the event name where spaces and other odd characters are converted into underscores.

Fields

  • event - (Required) A block which includes details of the event, detailed below.
  • observations - (Optional, unless sentiment and comments are present) The factual elements of the connection. This should be descriptive of just the facts. - String
  • sentiment - (Optional) How the user felt about the event. Choices include negative, neutral, or positive - Identifier
  • comments - (Optional) the textual reaction of the user, their feelings about the situation - String

event

  • name - (Required) The name of the event
  • date- (Required) The date the connection occurred - String in YYYY-MM-DD format
  • recurrence- (Optional) when this event repeats, detailed below

recurrence

  • starting - (Required) the date that the recurrence starts repeating - String in YYYY-MM-DD format
  • repeats- (Required) a recurrence string describing the schedule during which the event repeats.

repeats has two main sections:

  1. Frequency and Interval. When interval is 1, the number can be omitted. Examples: daily, weekly, monthly, yearly, every 2 weeks, every 3 days
  2. Predicate, which is specific to the type of frequency:

daily

For daily there is no predicate.

Examples:

  • daily
  • every 3 days

weekly

For weekly the predicate is the day of the week: on Friday, on Saturday and Sunday, on Monday, Wednesday and Friday. If this is missing, the system will assume that the schedule will repeat on the day of the week that the starting date falls on.

Examples:

  • weekly
  • every 2 weeks
  • every 2 weeks on Friday
  • every 4 weeks on Monday, Wednesday and Friday

monthly

For monthly the predicate can either list out the day of month or specify the position within the month that repeats.

For repeating on specific days of the month, list them out: 1st, 1st and 15th, 1st, 3rd and 10th. This is optional and if it's omitted the day of month is assumed to be the same day of month that the starting date falls on.

For repeating on the position within the month, use an ordinal expression, which has two parts: (1) The ordinal: first, second, third, fourth, fifth, next to last, last and the day specification, which is a day of the week (Sunday, Monday) or one of day, weekday, or weekend day.

Examples:

Specific days of the month:

  • monthly on the 1st and 15th
  • every 2 months on the 1st

Position within the month:

  • monthly on the first Sunday
  • monthly on the last day
  • every 3 months on the first Friday

yearly

For yearly the predicate lists out the months as above, with in as a preposition: in January, in January and February, in January, February and March. Just as above, if the month is not there the system assumes that the month is the same month the starting date falls within.

The yearly also can have the ordinal predicate, as specified above.

Examples:

  • yearly
  • yearly in January
  • yearly in May and November
  • yearly on the last Sunday
  • yearly in May on the last day
  • every 3 years
  • every 4 years on the first Tuesday

Examples

Upcoming

// located in ./work/tara_johnson/connections/2025-01-23_lunch.wrk
// Alex (the user) will have lunch with Tara on January 23, 2025.
// After the lunch he'll come back and write his observations and reactions
// about the upcoming connection.
event: {
  name: "Lunch"
  date: "2025-01-23"
}

Recurring

event: {
  name: "Lunch"
  date: "2025-01-23"
  recurring: {
    starting: "2025-01-23"
    repeats: "every 2 weeks"
  }
}

Journaled

// located in ./work/tara_johnson/connections/2025-01-23_lunch.wrk
// Alex (the user) had lunch with Tara on January 23, 2025.
// He wrote down the important facts of their interaction
// He also wrote down his feelings about the ineraction
event: {
  name: "Lunch"
  date: "2025-01-23"
}
observations: """
Talked about Project Gravy which is late
Tara has helped Kevin deliver on the containers feature.
"""
sentiment: positive
comments: """
Tara does struggle with some things but I'm impressed by her being
a team player, especially with Kevin.
"""

Workspace.toml

This is only for reference and is located in your workspace's directory.

Info

You cannot change the name of the app through this file.

It contains the name of the workspace and the version of the DSL.

name = "Your Workspace Name"
schema_version = 3

Schema Changes

The following changes occurred across schema_version values:

schema_versiondescriptionupgrade process
1initialadd workspace.toml with name and schema_version
2renamed journal to connections to prepare for other types of dataIn the work folder, for every individual listed, rename their journal folder to be named connections
3renamed groups to include non-manager usersin people.ppl, rename relationship to group, then rename base to network, direct_report to guide, and first_team to partner. See documentation.

Workspace Template

Once someone in your organization has created a workspace, there's no need to create a new one from scratch. You can share it with others in order to reuse shared concepts. Here's how you can do that:

  1. The new user will create a new nested folder on their computer called people/<workspace-name>, for example people/wincorp.

    Note

    The workspace folder is nested inside the people folder because if the user decides to create any new workspaces, they will create it inside this people folder.

  2. You, the original workspace creator, will copy your core.ppl file and assets folder with everything in it from your workspace folder and share it with them.

    Warning

    Ensure that your people.ppl file and your work folder is NOT included. These include your private entries that you will not want to share.

  3. The new user will put the shared core.ppl file and assets/* folder and contents in their newly created people folder on their computer.

  4. This new user will find the member associated with them in the core.ppl and copy their member ID. For example, if Kevin Osei was creating a user for himself, he would find this block in core.ppl and copy kevin_osei:

    member kevin_osei {
      first_name: "Kevin"
      last_name: "Osei"
      job: software_engineer_2
      email: "test-kevin-osei@wincorp.com"
    }
    
  5. The new user will then create their own people.ppl file inside their people/<workspace-name> folder.

  6. Inside that file, they will create their user by adding a user block that uses their ID from above. For example, Kevin Osei would type this in his people.ppl file:

    user kevin_osei {}
    
  7. This new user can now open this workspace in the People Work app by going to File > Open Workspace > Open Existing Workspace, and clicking on their newly created workspace folder.

Configuration

People Work is meant to be configuration-free while also providing easy out-of-the-box configuration offers that developers are accustomed to using.

There are two main configuration files:

  1. ~/.config/people/config.toml - configuration that is static and can be saved in a dotfiles repo.
  2. ~/.local/state/people/state.toml - configuration that is related to how the user is using the app and is machine-specific.

Application Configuration

This refers to global configuration for the user that can be saved in a dotfiles repo, does not change very often, is not sensitive, and is located in ~/.config/people/config.toml. The following properties are supported:

Default Workspaces Parent Directory

  • Value - default_workspaces_parent of type path.
  • Default - ~/Documents/People

The location of the parent folder that is used when a new workspace is created. The user might want to change this when they are using a synced folder location.

Example:

default_workspaces_parent = "~/Synced/Documents/People"

Workspaces

  • Value: workspaces of an array of paths
  • Default: [] (empty array)

The location workspaces that the user can switch between in the app.

Info

If any of the directories listed here no longer exist, they will be removed and the config file will be updated. This also applies to the current workspace in the state config.

Example:

workspaces = [
  "~/Documents/People/My Corp",
  "~/Documents/People/Local Tech Community"
]

State

This is only for reference and is located in ~/.local/state/people/state.toml. When you use the app it will update these values.

Current Workspace

  • Value: current_workspace that is a path
  • Default: none

The location workspaces that the user is currently working on. The app will automatically open to this location.

Example:

current_workspace = "~/Docuemnts/People/My Corp"