ftown 0.25.3 → 0.26.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/dist/coordination/board.d.ts +12 -0
- package/dist/coordination/board.js +240 -0
- package/dist/coordination/board.js.map +1 -0
- package/dist/coordination/card-store.d.ts +9 -0
- package/dist/coordination/card-store.js +188 -0
- package/dist/coordination/card-store.js.map +1 -0
- package/dist/coordination/contract.d.ts +236 -0
- package/dist/coordination/contract.js +63 -0
- package/dist/coordination/contract.js.map +1 -0
- package/dist/coordination/format.d.ts +5 -0
- package/dist/coordination/format.js +60 -0
- package/dist/coordination/format.js.map +1 -0
- package/dist/coordination/tree-events.d.ts +31 -0
- package/dist/coordination/tree-events.js +226 -0
- package/dist/coordination/tree-events.js.map +1 -0
- package/dist/coordination/wiring.d.ts +48 -0
- package/dist/coordination/wiring.js +143 -0
- package/dist/coordination/wiring.js.map +1 -0
- package/dist/coordination-cli.d.ts +34 -0
- package/dist/coordination-cli.js +460 -0
- package/dist/coordination-cli.js.map +1 -0
- package/dist/ftown-cli.js +9 -2
- package/dist/ftown-cli.js.map +1 -1
- package/dist/index.js +30 -7
- package/dist/index.js.map +1 -1
- package/dist/local-api-server.d.ts +6 -1
- package/dist/local-api-server.js +282 -5
- package/dist/local-api-server.js.map +1 -1
- package/dist/mail-delivery.d.ts +16 -2
- package/dist/mail-delivery.js +331 -77
- package/dist/mail-delivery.js.map +1 -1
- package/dist/mail-store.d.ts +7 -0
- package/dist/mail-store.js +71 -1
- package/dist/mail-store.js.map +1 -1
- package/dist/pull-request-events.d.ts +5 -0
- package/dist/pull-request-events.js +21 -1
- package/dist/pull-request-events.js.map +1 -1
- package/dist/security/bridge/permissions.js +20 -0
- package/dist/security/bridge/permissions.js.map +1 -1
- package/dist/types.d.ts +5 -1
- package/dist/wire-types.d.ts +17 -1
- package/dist/wire-types.js +1 -1
- package/dist/wire-types.js.map +1 -1
- package/package.json +2 -2
- package/skills/ftown/SKILL.md +29 -4
- package/skills/ftown/references/orchestrator.md +12 -7
- package/skills/ftown/references/sessions.md +45 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Activity } from '../attention-events.js';
|
|
2
|
+
import type { PullRequestState } from '../pull-request-status-protocol.js';
|
|
3
|
+
import type { Session } from '../types.js';
|
|
4
|
+
import type { BoardDeps, BoardServiceApi, CardStoreApi, CardStoreDeps, DigestProvider, MailEventSink, TreeEventKind, TreeEventLogApi, TreeEventLogDeps } from './contract.js';
|
|
5
|
+
export interface CoordinationSessionStore {
|
|
6
|
+
loadSession(id: string): Promise<Session | null>;
|
|
7
|
+
saveSession(session: Session): Promise<void>;
|
|
8
|
+
listSessions(): Promise<Session[]>;
|
|
9
|
+
sessionDir(id: string): string;
|
|
10
|
+
}
|
|
11
|
+
export interface CoordinationAttentionStore {
|
|
12
|
+
list(id: string): Promise<{
|
|
13
|
+
activity: Activity;
|
|
14
|
+
openCount: number;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
export interface CoordinationPrStatusResult {
|
|
18
|
+
state: PullRequestState;
|
|
19
|
+
stale: boolean;
|
|
20
|
+
checkedAt: string | null;
|
|
21
|
+
}
|
|
22
|
+
export interface CoordinationMailStore {
|
|
23
|
+
unreadCount(id: string): Promise<number>;
|
|
24
|
+
}
|
|
25
|
+
export interface CoordinationDeps {
|
|
26
|
+
store: CoordinationSessionStore;
|
|
27
|
+
attention: CoordinationAttentionStore;
|
|
28
|
+
prStatus: (url: string) => Promise<CoordinationPrStatusResult | null>;
|
|
29
|
+
mail: CoordinationMailStore;
|
|
30
|
+
publishSession: (s: Session) => void;
|
|
31
|
+
now: () => number;
|
|
32
|
+
/** Optional factory seams for unit tests using *Api fakes. */
|
|
33
|
+
createCards?: (deps: CardStoreDeps) => CardStoreApi;
|
|
34
|
+
createEvents?: (deps: TreeEventLogDeps) => TreeEventLogApi;
|
|
35
|
+
createBoard?: (deps: BoardDeps) => BoardServiceApi;
|
|
36
|
+
}
|
|
37
|
+
export interface Coordination {
|
|
38
|
+
cards: CardStoreApi;
|
|
39
|
+
events: TreeEventLogApi;
|
|
40
|
+
board: BoardServiceApi;
|
|
41
|
+
digest: DigestProvider;
|
|
42
|
+
mailSink: MailEventSink;
|
|
43
|
+
emit(session: Session, kind: TreeEventKind, summary: string, ref?: string): Promise<void>;
|
|
44
|
+
onSessionExit(sessionId: string): Promise<void>;
|
|
45
|
+
onSessionStart(sessionId: string): void;
|
|
46
|
+
}
|
|
47
|
+
export declare function rootOf(session: Pick<Session, 'id' | 'parentSessionId'>): string;
|
|
48
|
+
export declare function createCoordination(deps: CoordinationDeps): Coordination;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { BoardService } from './board.js';
|
|
2
|
+
import { CardStore } from './card-store.js';
|
|
3
|
+
import { TreeEventLog } from './tree-events.js';
|
|
4
|
+
export function rootOf(session) {
|
|
5
|
+
return session.parentSessionId ?? session.id;
|
|
6
|
+
}
|
|
7
|
+
function sameBlockedOn(a, b) {
|
|
8
|
+
if (a === undefined && b === undefined)
|
|
9
|
+
return true;
|
|
10
|
+
if (a === undefined || b === undefined)
|
|
11
|
+
return false;
|
|
12
|
+
return a.kind === b.kind && a.text === b.text && a.ref === b.ref;
|
|
13
|
+
}
|
|
14
|
+
function statusChanged(current, previous) {
|
|
15
|
+
if (!previous)
|
|
16
|
+
return true;
|
|
17
|
+
if (current.state !== previous.state)
|
|
18
|
+
return true;
|
|
19
|
+
if (current.headline !== previous.headline)
|
|
20
|
+
return true;
|
|
21
|
+
return !sameBlockedOn(current.blockedOn, previous.blockedOn);
|
|
22
|
+
}
|
|
23
|
+
function formatStatusSummary(card) {
|
|
24
|
+
const base = `${card.state}: ${card.headline}`;
|
|
25
|
+
if (card.state === 'blocked' && card.blockedOn) {
|
|
26
|
+
return `${base} — blocked on ${card.blockedOn.kind}: ${card.blockedOn.text}`;
|
|
27
|
+
}
|
|
28
|
+
return base;
|
|
29
|
+
}
|
|
30
|
+
export function createCoordination(deps) {
|
|
31
|
+
const events = (deps.createEvents ?? ((d) => new TreeEventLog(d)))({
|
|
32
|
+
sessionDir: (id) => deps.store.sessionDir(id),
|
|
33
|
+
now: deps.now,
|
|
34
|
+
});
|
|
35
|
+
const exitedSessions = new Set();
|
|
36
|
+
function onSessionStart(sessionId) {
|
|
37
|
+
exitedSessions.delete(sessionId);
|
|
38
|
+
}
|
|
39
|
+
async function emit(session, kind, summary, ref) {
|
|
40
|
+
if (kind === 'exit') {
|
|
41
|
+
if (exitedSessions.has(session.id))
|
|
42
|
+
return;
|
|
43
|
+
exitedSessions.add(session.id);
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const rootId = rootOf(session);
|
|
47
|
+
await events.append(rootId, {
|
|
48
|
+
sessionId: session.id,
|
|
49
|
+
sessionName: session.name,
|
|
50
|
+
kind,
|
|
51
|
+
summary,
|
|
52
|
+
...(ref !== undefined ? { ref } : {}),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.warn('[Coordination] Failed to emit tree event:', error instanceof Error ? error.message : String(error));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function onSessionExit(sessionId) {
|
|
60
|
+
if (exitedSessions.has(sessionId))
|
|
61
|
+
return;
|
|
62
|
+
await deps.store
|
|
63
|
+
.loadSession(sessionId)
|
|
64
|
+
.then((session) => {
|
|
65
|
+
if (session && (session.status === 'completed' || session.status === 'error')) {
|
|
66
|
+
return emit(session, 'exit', `exited: ${session.status}`);
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
.catch((error) => {
|
|
70
|
+
console.warn('[Coordination] Failed to load session on exit:', error instanceof Error ? error.message : String(error));
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const cards = (deps.createCards ?? ((d) => new CardStore(d)))({
|
|
74
|
+
loadSession: (id) => deps.store.loadSession(id),
|
|
75
|
+
saveSession: (session) => deps.store.saveSession(session),
|
|
76
|
+
now: deps.now,
|
|
77
|
+
onChange: async (saved, previous) => {
|
|
78
|
+
try {
|
|
79
|
+
deps.publishSession(saved);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.warn('[Coordination] Failed to publish session update:', error instanceof Error ? error.message : String(error));
|
|
83
|
+
}
|
|
84
|
+
if (saved.card && statusChanged(saved.card, previous)) {
|
|
85
|
+
await emit(saved, 'status', formatStatusSummary(saved.card));
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
const board = (deps.createBoard ?? ((d) => new BoardService(d)))({
|
|
90
|
+
loadSession: (id) => deps.store.loadSession(id),
|
|
91
|
+
listSessions: () => deps.store.listSessions(),
|
|
92
|
+
attention: async (id) => {
|
|
93
|
+
const page = await deps.attention.list(id);
|
|
94
|
+
return { activity: page.activity, openCount: page.openCount };
|
|
95
|
+
},
|
|
96
|
+
prStatus: (url) => deps.prStatus(url),
|
|
97
|
+
unreadMail: (id) => deps.mail.unreadCount(id),
|
|
98
|
+
events,
|
|
99
|
+
now: deps.now,
|
|
100
|
+
});
|
|
101
|
+
const digestCursors = new Map();
|
|
102
|
+
const digest = {
|
|
103
|
+
async digestFor(recipientSessionId) {
|
|
104
|
+
try {
|
|
105
|
+
const sessions = await deps.store.listSessions();
|
|
106
|
+
const hasChildren = sessions.some((s) => s.parentSessionId === recipientSessionId && s.id !== recipientSessionId);
|
|
107
|
+
if (!hasChildren)
|
|
108
|
+
return null;
|
|
109
|
+
let since = digestCursors.get(recipientSessionId);
|
|
110
|
+
if (since === undefined) {
|
|
111
|
+
since = await events.head(recipientSessionId);
|
|
112
|
+
digestCursors.set(recipientSessionId, since);
|
|
113
|
+
}
|
|
114
|
+
const result = await board.digest(recipientSessionId, since);
|
|
115
|
+
digestCursors.set(recipientSessionId, result.cursor);
|
|
116
|
+
return result.line;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
const mailSink = {
|
|
124
|
+
async onAccepted(message, recipient) {
|
|
125
|
+
try {
|
|
126
|
+
if (message.type !== 'result')
|
|
127
|
+
return;
|
|
128
|
+
const sender = await deps.store.loadSession(message.from);
|
|
129
|
+
if (!sender)
|
|
130
|
+
return;
|
|
131
|
+
if (rootOf(sender) !== recipient.id)
|
|
132
|
+
return;
|
|
133
|
+
const firstLine = (message.body.split(/\r?\n/, 1)[0] ?? '').slice(0, 200);
|
|
134
|
+
await emit(sender, 'result', firstLine);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.warn('[Coordination] Failed to handle accepted mail event:', error instanceof Error ? error.message : String(error));
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
return { cards, events, board, digest, mailSink, emit, onSessionExit, onSessionStart };
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=wiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiring.js","sourceRoot":"","sources":["../../src/coordination/wiring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Board, type BoardWaitCondition, type CardPatch, type CardProgress, type TreeEvent } from './coordination/contract.js';
|
|
2
|
+
/** One local-API call; injectable so tests need no bridge. */
|
|
3
|
+
export type CoordinationApiFn = (method: string, path: string, body?: unknown) => Promise<unknown>;
|
|
4
|
+
export interface CoordinationCliDeps {
|
|
5
|
+
api: CoordinationApiFn;
|
|
6
|
+
now: () => number;
|
|
7
|
+
env: NodeJS.ProcessEnv;
|
|
8
|
+
log: (text: string) => void;
|
|
9
|
+
errorLog: (text: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const WAIT_DEFAULT_TIMEOUT_SECONDS = 300;
|
|
12
|
+
export declare const WAIT_MAX_TIMEOUT_SECONDS = 300;
|
|
13
|
+
/** Usage problem: message printed, exit code 2. */
|
|
14
|
+
export declare class UsageError extends Error {
|
|
15
|
+
readonly usage?: string | undefined;
|
|
16
|
+
constructor(message: string, usage?: string | undefined);
|
|
17
|
+
}
|
|
18
|
+
export declare function parseProgress(value: string): CardProgress;
|
|
19
|
+
export interface StatusSetFlags {
|
|
20
|
+
state?: string;
|
|
21
|
+
headline?: string;
|
|
22
|
+
/** string value, false for --no-progress, undefined when absent */
|
|
23
|
+
progress?: string | boolean;
|
|
24
|
+
on?: string;
|
|
25
|
+
text?: string;
|
|
26
|
+
/** string value, false for --no-next, undefined when absent */
|
|
27
|
+
next?: string | boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function buildCardPatch(flags: StatusSetFlags): CardPatch;
|
|
30
|
+
/** Pure wait-condition evaluation over a fetched board and the events that arrived. */
|
|
31
|
+
export declare function evaluateWaitCondition(condition: BoardWaitCondition, board: Board, events: readonly TreeEvent[]): boolean;
|
|
32
|
+
export declare function runStatus(argv: string[], deps?: Partial<CoordinationCliDeps>): Promise<number>;
|
|
33
|
+
export declare function runBoard(argv: string[], deps?: Partial<CoordinationCliDeps>): Promise<number>;
|
|
34
|
+
export declare function runEvents(argv: string[], deps?: Partial<CoordinationCliDeps>): Promise<number>;
|