Browse Source

rules: Adding cursorrules technical aspects

qrcode-capacitor
Matthew Raymer 2 months ago
parent
commit
3ca82fe762
  1. 330
      README-context.md

330
README-context.md

@ -0,0 +1,330 @@
# Time Safari Context
## Project Overview
Time Safari is an application designed to foster community building through gifts, gratitude, and collaborative projects. The app should make it extremely easy and intuitive for users of any age and capability to recognize contributions, build trust networks, and organize collective action. It is built on services that preserve privacy and data sovereignty.
The ultimate goals of Time Safari are two-fold:
1. **Connect** Make it easy, rewarding, and non-threatening for people to connect with others who have similar interests, and to initiate activities together. This helps people accomplish and learn from other individuals in less-structured environments; moreover, it helps them discover who they want to continue to support and with whom they want to maintain relationships.
2. **Reveal** Widely advertise the great support and rewards that are being given and accepted freely, especially non-monetary ones. Using visuals and text, display the kind of impact that gifts are making in the lives of others. Also show useful and engaging reports of project statistics and personal accomplishments.
## Core Approaches
Time Safari should help everyday users build meaningful connections and organize collective efforts by:
1. **Recognizing Contributions**: Creating permanent, verifiable records of gifts and contributions people give to each other and their communities.
2. **Facilitating Collaboration**: Making it ridiculously easy for people to ask for or propose help on projects and interests that matter to them.
3. **Building Trust Networks**: Enabling users to maintain their network and activity visibility. Developing reputation through verified contributions and references, which can be selectively shown to others outside the network.
4. **Preserving Privacy**: Ensuring personal identifiers are only shared with explicitly authorized contacts, allowing private individuals including children to participate safely.
5. **Engaging Content**: Displaying people's records in compelling stories, and highlighting those projects that are lifting people's lives long-term, both in physical support and in emotional-spiritual-creative thriving.
## Technical Foundation
This application is built on a privacy-preserving claims architecture (via endorser.ch) with these key characteristics:
- **Decentralized Identifiers (DIDs)**: User identities are based on public/private key pairs stored on their devices
- **Cryptographic Verification**: All claims and confirmations are cryptographically signed
- **User-Controlled Visibility**: Users explicitly control who can see their identifiers and data
- **Merkle-Chained Claims**: Claims are cryptographically chained for verification and integrity
- **Native and Web App**: Works on iOS, Android, and web browsers
## User Journey
The typical progression of usage follows these stages:
1. **Gratitude & Recognition**: Users begin by expressing and recording gratitude for gifts received, building a foundation of acknowledgment.
2. **Project Proposals**: Users propose projects and ideas, reaching out to connect with others who share similar interests.
3. **Action Triggers**: Offers of help serve as triggers and motivations to execute proposed projects, moving from ideas to action.
## Context for LLM Development
When developing new functionality for Time Safari, consider these design principles:
1. **Accessibility First**: Features should be usable by non-technical users with minimal learning curve.
2. **Privacy by Design**: All features must respect user privacy and data sovereignty.
3. **Progressive Enhancement**: Core functionality should work across all devices, with richer experiences where supported.
4. **Voluntary Collaboration**: The system should enable but never coerce participation.
5. **Trust Building**: Features should help build verifiable trust between users.
6. **Network Effects**: Consider how features scale as more users join the platform.
7. **Low Resource Requirements**: The system should be lightweight enough to run on inexpensive devices users already own.
## Use Cases to Support
LLM development should focus on enhancing these key use cases:
1. **Community Building**: Tools that help people find others with shared interests and values.
2. **Project Coordination**: Features that make it easy to propose collaborative projects and to submit suggestions and offers to existing ones.
3. **Reputation Building**: Methods for users to showcase their contributions and reliability, in contexts where they explicitly reveal that information.
4. **Governance Experimentation**: Features that facilitate decision-making and collective governance.
## Constraints
When developing new features, be mindful of these constraints:
1. **Privacy Preservation**: User identifiers must remain private except when explicitly shared.
2. **Platform Limitations**: Features must work within the constraints of the target app platforms, while aiming to leverage the best platform technology available.
3. **Endorser API Limitations**: Backend features are constrained by the endorser.ch API capabilities.
4. **Performance on Low-End Devices**: The application should remain performant on older/simpler devices.
5. **Offline-First When Possible**: Key functionality should work offline when feasible.
# Core Development Principles
- Ensure all components support accessibility first design
- Implement privacy-preserving features by default
- Support progressive enhancement across devices
- Enable voluntary collaboration features
- Build trust-enabling interactions
- Optimize for low resource requirements
- Support offline-first functionality where possible
# Vue Component Structure
- Use `@Options`, `@Ref`, `@Prop`, `@Emit`, and `@Watch` decorators for clear component structure
- Extend `Vue` class with proper type annotations for props, refs, and methods
- Use Tailwind utility classes for accessible and responsive design
- Avoid `setup()` or Composition API; use class syntax consistently
- Keep methods pure when possible; extract logic into utilities
- Ensure lifecycle methods are clearly defined inside class
- Use semantic HTML + Tailwind classes for styling
[rules.component-class]
description = "Create a privacy-aware Vue 3 component"
trigger = "vfd-component"
insert = """
import { Options, Vue } from 'vue-facing-decorator'
import { PlatformService } from '@/services/platform'
@Options({
name: 'MyComponent',
props: {},
emits: ['error', 'privacy-consent'],
})
export default class MyComponent extends Vue {
private platformService = new PlatformService()
// Lifecycle
mounted() {
this.checkPrivacyConsent()
}
// Privacy check
private async checkPrivacyConsent() {
const hasConsent = await this.platformService.getPrivacyConsent()
if (!hasConsent) {
this.$emit('privacy-consent-needed')
}
}
// Error handling
protected handleError(error: Error) {
console.error('Component error:', error)
this.$emit('error', error)
}
}
"""
[rules.decorator-prop]
description = "Add a validated prop with privacy considerations"
trigger = "vfd-prop"
insert = """
@Prop({
required: true,
validator: (value: any) => {
// Add validation logic
return typeof value === 'string' && value.length > 0
}
})
propName!: string
"""
[rules.decorator-watch]
description = "Watch a property with offline support"
trigger = "vfd-watch"
insert = """
@Watch('myProp')
async onMyPropChanged(newVal: any, oldVal: any) {
try {
// Handle offline state
if (!navigator.onLine) {
await this.queueOfflineChange(newVal)
return
}
await this.processChange(newVal)
} catch (error) {
this.handleError(error as Error)
}
}
"""
[rules.decorator-emit]
description = "Emit a privacy-aware event"
trigger = "vfd-emit"
insert = """
@Emit('data-update')
async emitPrivateData() {
const privateData = await this.platformService.getEncryptedData()
return privateData
}
"""
[rules.component-template]
description = "Create an accessible component template"
trigger = "vfd-component-full"
insert = """
<template>
<div
class="p-4 bg-white dark:bg-gray-800"
:aria-label="accessibilityLabel"
>
<h2
class="text-lg font-semibold text-gray-900 dark:text-white"
:id="headingId"
>
{{ title }}
</h2>
<div
class="mt-4"
:aria-labelledby="headingId"
>
<slot></slot>
</div>
<!-- Offline indicator -->
<div
v-if="!isOnline"
class="text-sm text-amber-600 mt-2"
role="alert"
>
Currently offline - changes will sync when connection is restored
</div>
</div>
</template>
<script lang="ts">
import { Options, Vue } from 'vue-facing-decorator'
import { generateUniqueId } from '@/utils/accessibility'
@Options({
name: 'MyComponent',
props: {
title: String,
accessibilityLabel: String
}
})
export default class MyComponent extends Vue {
title!: string
accessibilityLabel!: string
headingId = generateUniqueId()
isOnline = navigator.onLine
mounted() {
window.addEventListener('online', this.updateOnlineStatus)
window.addEventListener('offline', this.updateOnlineStatus)
}
beforeUnmount() {
window.removeEventListener('online', this.updateOnlineStatus)
window.removeEventListener('offline', this.updateOnlineStatus)
}
updateOnlineStatus() {
this.isOnline = navigator.onLine
}
}
</script>
"""
[rules.async-method]
description = "Add an async method with offline support and error handling"
trigger = "vfd-async"
insert = """
async fetchData(): Promise<void> {
try {
if (!navigator.onLine) {
const cachedData = await this.getCachedData()
if (cachedData) {
this.data = cachedData
return
}
throw new Error('No cached data available offline')
}
const response = await this.apiService.getData()
this.data = response
await this.cacheData(response)
} catch (error) {
this.handleError(error as Error)
this.$emit('error', error)
}
}
"""
[rules.privacy-aware-component]
description = "Create a privacy-aware component with DID handling"
trigger = "vfd-privacy"
insert = """
import { Options, Vue } from 'vue-facing-decorator'
import { PlatformService } from '@/services/platform'
import { DidService } from '@/services/did'
@Options({
name: 'PrivacyAwareComponent',
props: {
requiredPermissions: Array
}
})
export default class PrivacyAwareComponent extends Vue {
private platformService = new PlatformService()
private didService = new DidService()
requiredPermissions!: string[]
userDid = ''
async mounted() {
await this.checkPermissions()
await this.initializeDid()
}
private async initializeDid() {
try {
this.userDid = await this.didService.getCurrentDid()
} catch (error) {
this.handleError(error as Error)
}
}
private async checkPermissions() {
for (const permission of this.requiredPermissions) {
const hasPermission = await this.platformService.checkPermission(permission)
if (!hasPermission) {
this.$emit('permission-required', permission)
return
}
}
}
}
"""
Loading…
Cancel
Save