mirror of
https://github.com/kennethnym/aris.git
synced 2026-03-20 00:51:20 +00:00
Compare commits
2 Commits
feat/calda
...
feat/feed-
| Author | SHA1 | Date | |
|---|---|---|---|
|
f806b78fb7
|
|||
|
65ca50bf36
|
@@ -1,43 +0,0 @@
|
||||
---
|
||||
name: gpg-commit-signing
|
||||
description: Sign git commits with GPG in non-interactive environments. Use when committing code and the `GPG_PRIVATE_KEY_PASSPHRASE` environment variable is available. Triggers on "commit", "sign commit", "GPG", "git commit -S", or any git operation requiring signed commits.
|
||||
---
|
||||
|
||||
# GPG Commit Signing
|
||||
|
||||
Sign commits in headless/non-interactive environments where `/dev/tty` is unavailable.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Check whether `GPG_PRIVATE_KEY_PASSPHRASE` is set:
|
||||
|
||||
```bash
|
||||
test -n "$GPG_PRIVATE_KEY_PASSPHRASE" && echo "available" || echo "not set"
|
||||
```
|
||||
|
||||
If not set, skip signing — commit without `-S`.
|
||||
|
||||
2. Try a direct signed commit first — the environment may already have loopback pinentry configured:
|
||||
|
||||
```bash
|
||||
git commit -S -m "message"
|
||||
```
|
||||
|
||||
If this succeeds, no further steps are needed.
|
||||
|
||||
3. If step 2 fails with a `/dev/tty` error, use `--pinentry-mode loopback` via a wrapper script:
|
||||
|
||||
```bash
|
||||
printf '#!/bin/sh\ngpg --batch --pinentry-mode loopback --passphrase "$GPG_PRIVATE_KEY_PASSPHRASE" "$@"\n' > /tmp/gpg-sign.sh
|
||||
chmod +x /tmp/gpg-sign.sh
|
||||
git -c gpg.program=/tmp/gpg-sign.sh commit -S -m "message"
|
||||
rm /tmp/gpg-sign.sh
|
||||
```
|
||||
|
||||
This passes the passphrase directly to gpg on each signing invocation, bypassing the need for a configured gpg-agent.
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- Do not echo or log `GPG_PRIVATE_KEY_PASSPHRASE`.
|
||||
- Do not commit without `-S` when the passphrase is available — the project expects signed commits.
|
||||
- Do not leave wrapper scripts on disk after committing.
|
||||
@@ -177,7 +177,7 @@ export class FeedEngine<TItems extends FeedItem = FeedItem> {
|
||||
items: processedItems,
|
||||
groupedItems,
|
||||
errors: postProcessorErrors,
|
||||
} = await this.applyPostProcessors(items as TItems[], context, errors)
|
||||
} = await this.applyPostProcessors(items as TItems[], errors)
|
||||
|
||||
const result: FeedResult<TItems> = {
|
||||
context,
|
||||
@@ -294,7 +294,6 @@ export class FeedEngine<TItems extends FeedItem = FeedItem> {
|
||||
|
||||
private async applyPostProcessors(
|
||||
items: TItems[],
|
||||
context: Context,
|
||||
errors: SourceError[],
|
||||
): Promise<{ items: TItems[]; groupedItems: ItemGroup[]; errors: SourceError[] }> {
|
||||
let currentItems = items
|
||||
@@ -305,7 +304,7 @@ export class FeedEngine<TItems extends FeedItem = FeedItem> {
|
||||
for (const processor of this.postProcessors) {
|
||||
const snapshot = currentItems
|
||||
try {
|
||||
const enhancement = await processor(currentItems, context)
|
||||
const enhancement = await processor(currentItems)
|
||||
|
||||
if (enhancement.additionalItems?.length) {
|
||||
// Post-processors operate on FeedItem[] without knowledge of TItems.
|
||||
@@ -413,7 +412,7 @@ export class FeedEngine<TItems extends FeedItem = FeedItem> {
|
||||
items: processedItems,
|
||||
groupedItems,
|
||||
errors: postProcessorErrors,
|
||||
} = await this.applyPostProcessors(items as TItems[], this.context, errors)
|
||||
} = await this.applyPostProcessors(items as TItems[], errors)
|
||||
|
||||
const result: FeedResult<TItems> = {
|
||||
context: this.context,
|
||||
|
||||
@@ -490,10 +490,12 @@ describe("FeedPostProcessor", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const engine = new FeedEngine().register(source).registerPostProcessor(async () => {
|
||||
callCount++
|
||||
return {}
|
||||
})
|
||||
const engine = new FeedEngine()
|
||||
.register(source)
|
||||
.registerPostProcessor(async () => {
|
||||
callCount++
|
||||
return {}
|
||||
})
|
||||
|
||||
engine.start()
|
||||
|
||||
@@ -532,10 +534,12 @@ describe("FeedPostProcessor", () => {
|
||||
},
|
||||
}
|
||||
|
||||
const engine = new FeedEngine().register(source).registerPostProcessor(async () => {
|
||||
callCount++
|
||||
return {}
|
||||
})
|
||||
const engine = new FeedEngine()
|
||||
.register(source)
|
||||
.registerPostProcessor(async () => {
|
||||
callCount++
|
||||
return {}
|
||||
})
|
||||
|
||||
engine.start()
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Context } from "./context"
|
||||
import type { FeedItem } from "./feed"
|
||||
|
||||
export interface ItemGroup {
|
||||
@@ -23,4 +22,4 @@ export interface FeedEnhancement {
|
||||
* A function that transforms feed items and produces enhancement directives.
|
||||
* Use named functions for meaningful error attribution.
|
||||
*/
|
||||
export type FeedPostProcessor = (items: FeedItem[], context: Context) => Promise<FeedEnhancement>
|
||||
export type FeedPostProcessor = (items: FeedItem[]) => Promise<FeedEnhancement>
|
||||
|
||||
@@ -4,10 +4,10 @@ import { TimeRelevance, UnknownActionError } from "@aris/core"
|
||||
import { DAVClient } from "tsdav"
|
||||
|
||||
import type { CalDavDAVClient, CalDavEventData, CalDavFeedItem } from "./types.ts"
|
||||
import { CalDavEventStatus } from "./types.ts"
|
||||
|
||||
import { CalDavCalendarKey, type CalendarContext } from "./calendar-context.ts"
|
||||
import { parseICalEvents } from "./ical-parser.ts"
|
||||
import { CalDavEventStatus, CalDavFeedItemType } from "./types.ts"
|
||||
|
||||
// -- Source options --
|
||||
|
||||
@@ -340,7 +340,7 @@ export function computeSignals(
|
||||
function createFeedItem(event: CalDavEventData, now: Date, timeZone?: string): CalDavFeedItem {
|
||||
return {
|
||||
id: `caldav-event-${event.uid}${event.recurrenceId ? `-${event.recurrenceId}` : ""}`,
|
||||
type: CalDavFeedItemType.Event,
|
||||
type: "caldav-event",
|
||||
timestamp: now,
|
||||
data: event,
|
||||
signals: computeSignals(event, now, timeZone),
|
||||
|
||||
@@ -5,7 +5,6 @@ export {
|
||||
AttendeeRole,
|
||||
AttendeeStatus,
|
||||
CalDavEventStatus,
|
||||
CalDavFeedItemType,
|
||||
type CalDavAlarm,
|
||||
type CalDavAttendee,
|
||||
type CalDavDAVCalendar,
|
||||
|
||||
@@ -64,17 +64,9 @@ export interface CalDavEventData extends Record<string, unknown> {
|
||||
recurrenceId: string | null
|
||||
}
|
||||
|
||||
// -- Feed item type --
|
||||
|
||||
export const CalDavFeedItemType = {
|
||||
Event: "caldav-event",
|
||||
} as const
|
||||
|
||||
export type CalDavFeedItemType = (typeof CalDavFeedItemType)[keyof typeof CalDavFeedItemType]
|
||||
|
||||
// -- Feed item --
|
||||
|
||||
export type CalDavFeedItem = FeedItem<typeof CalDavFeedItemType.Event, CalDavEventData>
|
||||
export type CalDavFeedItem = FeedItem<"caldav-event", CalDavEventData>
|
||||
|
||||
// -- DAV client interface --
|
||||
|
||||
|
||||
Reference in New Issue
Block a user