Slice 1 polish: archive dormant code, merge work-os into primitives, add futures
- Archive dormant apps (daemon, desktop, native, tui) and superseded packages/server into repos/ for reference - Archive 21 dead web components (chat page shell, work-os cluster, strays) into repos/web/; keep reused message-rendering primitives in components/chat - Merge @code/work-os into @code/primitives; work.ts absorbed via ./work subpath and barrel export; update all four importers - Add docs/futures.md tracking audio/video (blocked at Flue + provider), web layout cleanup, and message rendering quality - Repoint dev:zopu script to @code/agents (the live Flue server) - Note repos/ reference-code convention in AGENTS.md
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
"./project-work": "./src/project-work.ts",
|
||||
"./project-workspace": "./src/project-workspace.ts",
|
||||
"./signal": "./src/signal.ts",
|
||||
"./smoke": "./src/smoke.ts"
|
||||
"./smoke": "./src/smoke.ts",
|
||||
"./work": "./src/work.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"check-types": "tsc --noEmit",
|
||||
@@ -22,10 +23,10 @@
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentos-software/codex-cli": "0.3.4",
|
||||
"@agentos-software/git": "0.3.3",
|
||||
"@rivet-dev/agentos": "catalog:",
|
||||
"effect": "catalog:",
|
||||
"@agentos-software/codex-cli": "0.3.4"
|
||||
"effect": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@code/config": "workspace:*",
|
||||
|
||||
@@ -9,3 +9,4 @@ export * from "./project-workspace";
|
||||
export * from "./project-work";
|
||||
export * from "./signal";
|
||||
export * from "./smoke";
|
||||
export * from "./work";
|
||||
|
||||
134
packages/primitives/src/work.test.ts
Normal file
134
packages/primitives/src/work.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { Effect } from "effect";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import {
|
||||
projectWorkNotices,
|
||||
signalAttachedEvent,
|
||||
workDraftFromSignal,
|
||||
workProposedEventFromSignal,
|
||||
} from "./work";
|
||||
|
||||
describe("workDraftFromSignal", () => {
|
||||
test("creates a proposed Work draft from Signal meaning", async () => {
|
||||
const draft = await Effect.runPromise(
|
||||
workDraftFromSignal({
|
||||
desiredOutcome: "The phone flow is usable.",
|
||||
summary: "The current mobile workspace is hard to test.",
|
||||
title: "Make Slice 1 phone-testable",
|
||||
})
|
||||
);
|
||||
|
||||
expect(draft).toEqual({
|
||||
objective: "The phone flow is usable.",
|
||||
title: "Make Slice 1 phone-testable",
|
||||
});
|
||||
});
|
||||
|
||||
test("rejects empty Signal meaning", async () => {
|
||||
await expect(
|
||||
Effect.runPromise(
|
||||
workDraftFromSignal({ desiredOutcome: "", summary: "", title: "" })
|
||||
)
|
||||
).rejects.toMatchObject({ reason: "InvalidInput" });
|
||||
});
|
||||
|
||||
test("constructs stable proposed and attached event drafts", async () => {
|
||||
const proposed = await Effect.runPromise(
|
||||
workProposedEventFromSignal({
|
||||
organizationId: "org-1",
|
||||
projectId: "project-1",
|
||||
signalId: "signal-1",
|
||||
title: " Improve the phone flow ",
|
||||
})
|
||||
);
|
||||
const attached = await Effect.runPromise(
|
||||
signalAttachedEvent({
|
||||
signal: {
|
||||
organizationId: "org-1",
|
||||
projectId: "project-1",
|
||||
signalId: "signal-2",
|
||||
title: "Reuse the existing outcome",
|
||||
},
|
||||
work: {
|
||||
organizationId: "org-1",
|
||||
projectId: "project-1",
|
||||
workId: "work-1",
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
expect(proposed).toEqual({
|
||||
data: { signalId: "signal-1", title: "Improve the phone flow" },
|
||||
idempotencyKey: "proposed:signal-1",
|
||||
kind: "work.proposed",
|
||||
});
|
||||
expect(attached).toEqual({
|
||||
data: { signalId: "signal-2", title: "Reuse the existing outcome" },
|
||||
idempotencyKey: "signal:signal-2",
|
||||
kind: "signal.attached",
|
||||
});
|
||||
});
|
||||
|
||||
test("rejects a cross-project attachment", async () => {
|
||||
await expect(
|
||||
Effect.runPromise(
|
||||
signalAttachedEvent({
|
||||
signal: {
|
||||
organizationId: "org-1",
|
||||
projectId: "project-2",
|
||||
signalId: "signal-1",
|
||||
title: "Cross project",
|
||||
},
|
||||
work: {
|
||||
organizationId: "org-1",
|
||||
projectId: "project-1",
|
||||
workId: "work-1",
|
||||
},
|
||||
})
|
||||
)
|
||||
).rejects.toMatchObject({ reason: "ProjectMismatch" });
|
||||
});
|
||||
|
||||
test("projects proposed Work events into chronological notices", () => {
|
||||
expect(
|
||||
projectWorkNotices([
|
||||
{
|
||||
_id: "work-2",
|
||||
events: [{ _id: "event-2", createdAt: 20, kind: "work.proposed" }],
|
||||
signals: [
|
||||
{
|
||||
sources: [{ messageId: "message-2", rawText: "Second" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
_id: "work-1",
|
||||
events: [
|
||||
{ _id: "event-1", createdAt: 10, kind: "work.proposed" },
|
||||
{ _id: "event-3", createdAt: 30, kind: "signal.attached" },
|
||||
],
|
||||
signals: [
|
||||
{
|
||||
sources: [{ messageId: "message-1", rawText: "First" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
).toEqual([
|
||||
{
|
||||
createdAt: 10,
|
||||
eventId: "event-1",
|
||||
sourceMessageIds: ["message-1"],
|
||||
sourceTexts: ["First"],
|
||||
workId: "work-1",
|
||||
},
|
||||
{
|
||||
createdAt: 20,
|
||||
eventId: "event-2",
|
||||
sourceMessageIds: ["message-2"],
|
||||
sourceTexts: ["Second"],
|
||||
workId: "work-2",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
231
packages/primitives/src/work.ts
Normal file
231
packages/primitives/src/work.ts
Normal file
@@ -0,0 +1,231 @@
|
||||
import { Array as EffectArray, Effect, Order, Schema } from "effect";
|
||||
|
||||
const MeaningfulString = Schema.String.check(
|
||||
Schema.makeFilter((value) => value.trim().length > 0, {
|
||||
expected: "a non-empty string",
|
||||
})
|
||||
);
|
||||
|
||||
export const WorkStatus = Schema.Literal("proposed");
|
||||
export type WorkStatus = typeof WorkStatus.Type;
|
||||
|
||||
export const WorkDraft = Schema.Struct({
|
||||
objective: MeaningfulString,
|
||||
title: MeaningfulString,
|
||||
});
|
||||
export type WorkDraft = typeof WorkDraft.Type;
|
||||
|
||||
export const SignalProblem = Schema.Struct({
|
||||
desiredOutcome: MeaningfulString,
|
||||
summary: MeaningfulString,
|
||||
title: MeaningfulString,
|
||||
});
|
||||
|
||||
export const WorkCommandReason = Schema.Literals([
|
||||
"InvalidInput",
|
||||
"ProjectMismatch",
|
||||
"TitleTooLong",
|
||||
"ObjectiveTooLong",
|
||||
]);
|
||||
export type WorkCommandReason = typeof WorkCommandReason.Type;
|
||||
|
||||
export class WorkCommandError extends Schema.TaggedErrorClass<WorkCommandError>()(
|
||||
"WorkCommandError",
|
||||
{
|
||||
message: Schema.String,
|
||||
reason: WorkCommandReason,
|
||||
}
|
||||
) {}
|
||||
|
||||
export const workDraftFromSignal = Effect.fn("Work.draftFromSignal")(
|
||||
function* workDraftFromSignal(input: unknown) {
|
||||
const problem = yield* Schema.decodeUnknownEffect(SignalProblem)(
|
||||
input
|
||||
).pipe(
|
||||
Effect.mapError(
|
||||
() =>
|
||||
new WorkCommandError({
|
||||
message: "Signal is missing a valid problem statement",
|
||||
reason: "InvalidInput",
|
||||
})
|
||||
)
|
||||
);
|
||||
const title = problem.title.trim();
|
||||
const objective = problem.desiredOutcome.trim();
|
||||
|
||||
if (title.length > 160) {
|
||||
return yield* new WorkCommandError({
|
||||
message: "Work title must be 160 characters or fewer",
|
||||
reason: "TitleTooLong",
|
||||
});
|
||||
}
|
||||
if (objective.length > 2000) {
|
||||
return yield* new WorkCommandError({
|
||||
message: "Work objective must be 2000 characters or fewer",
|
||||
reason: "ObjectiveTooLong",
|
||||
});
|
||||
}
|
||||
|
||||
return { objective, title } satisfies WorkDraft;
|
||||
}
|
||||
);
|
||||
|
||||
const WorkIdentity = Schema.Struct({
|
||||
organizationId: MeaningfulString,
|
||||
projectId: MeaningfulString,
|
||||
workId: MeaningfulString,
|
||||
});
|
||||
|
||||
const SignalIdentity = Schema.Struct({
|
||||
organizationId: MeaningfulString,
|
||||
projectId: MeaningfulString,
|
||||
signalId: MeaningfulString,
|
||||
title: MeaningfulString,
|
||||
});
|
||||
|
||||
const WorkAttachmentInput = Schema.Struct({
|
||||
signal: SignalIdentity,
|
||||
work: WorkIdentity,
|
||||
});
|
||||
|
||||
export const WorkEventKind = Schema.Literals([
|
||||
"work.proposed",
|
||||
"signal.attached",
|
||||
]);
|
||||
export type WorkEventKind = typeof WorkEventKind.Type;
|
||||
|
||||
export const WorkEventDraft = Schema.Struct({
|
||||
data: Schema.Struct({
|
||||
signalId: MeaningfulString,
|
||||
title: MeaningfulString,
|
||||
}),
|
||||
idempotencyKey: MeaningfulString,
|
||||
kind: WorkEventKind,
|
||||
});
|
||||
export type WorkEventDraft = typeof WorkEventDraft.Type;
|
||||
|
||||
export const workProposedEventFromSignal = Effect.fn(
|
||||
"Work.proposedEventFromSignal"
|
||||
)(function* workProposedEventFromSignal(input: unknown) {
|
||||
const signal = yield* Schema.decodeUnknownEffect(SignalIdentity)(input).pipe(
|
||||
Effect.mapError(
|
||||
() =>
|
||||
new WorkCommandError({
|
||||
message: "Signal identity is invalid",
|
||||
reason: "InvalidInput",
|
||||
})
|
||||
)
|
||||
);
|
||||
return {
|
||||
data: { signalId: signal.signalId, title: signal.title.trim() },
|
||||
idempotencyKey: `proposed:${signal.signalId}`,
|
||||
kind: "work.proposed",
|
||||
} satisfies WorkEventDraft;
|
||||
});
|
||||
|
||||
export const signalAttachedEvent = Effect.fn("Work.signalAttachedEvent")(
|
||||
function* signalAttachedEvent(input: unknown) {
|
||||
const attachment = yield* Schema.decodeUnknownEffect(WorkAttachmentInput)(
|
||||
input
|
||||
).pipe(
|
||||
Effect.mapError(
|
||||
() =>
|
||||
new WorkCommandError({
|
||||
message: "Work attachment input is invalid",
|
||||
reason: "InvalidInput",
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
attachment.signal.organizationId !== attachment.work.organizationId ||
|
||||
attachment.signal.projectId !== attachment.work.projectId
|
||||
) {
|
||||
return yield* new WorkCommandError({
|
||||
message: "Signal and Work must belong to the same project",
|
||||
reason: "ProjectMismatch",
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
data: {
|
||||
signalId: attachment.signal.signalId,
|
||||
title: attachment.signal.title.trim(),
|
||||
},
|
||||
idempotencyKey: `signal:${attachment.signal.signalId}`,
|
||||
kind: "signal.attached",
|
||||
} satisfies WorkEventDraft;
|
||||
}
|
||||
);
|
||||
|
||||
const WorkNoticeInput = Schema.Array(
|
||||
Schema.Struct({
|
||||
_id: MeaningfulString,
|
||||
events: Schema.Array(
|
||||
Schema.Struct({
|
||||
_id: MeaningfulString,
|
||||
createdAt: Schema.Number,
|
||||
kind: WorkEventKind,
|
||||
})
|
||||
),
|
||||
signals: Schema.Array(
|
||||
Schema.Struct({
|
||||
sources: Schema.Array(
|
||||
Schema.Struct({ messageId: MeaningfulString, rawText: Schema.String })
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
export interface WorkNotice {
|
||||
readonly createdAt: number;
|
||||
readonly eventId: string;
|
||||
readonly sourceMessageIds: readonly string[];
|
||||
readonly sourceTexts: readonly string[];
|
||||
readonly workId: string;
|
||||
}
|
||||
|
||||
const projectWorkNoticesEffect = Effect.fn("Work.projectNotices")(
|
||||
function* projectWorkNoticesEffect(input: unknown) {
|
||||
const works = yield* Schema.decodeUnknownEffect(WorkNoticeInput)(
|
||||
input
|
||||
).pipe(
|
||||
Effect.mapError(
|
||||
() =>
|
||||
new WorkCommandError({
|
||||
message: "Work notice data is invalid",
|
||||
reason: "InvalidInput",
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const notices = works.flatMap((work) => {
|
||||
const sourceMessageIds = work.signals.flatMap((signal) =>
|
||||
signal.sources.map((source) => source.messageId)
|
||||
);
|
||||
const sourceTexts = work.signals.flatMap((signal) =>
|
||||
signal.sources.map((source) => source.rawText)
|
||||
);
|
||||
return work.events
|
||||
.filter((event) => event.kind === "work.proposed")
|
||||
.map(
|
||||
(event): WorkNotice => ({
|
||||
createdAt: event.createdAt,
|
||||
eventId: event._id,
|
||||
sourceMessageIds,
|
||||
sourceTexts,
|
||||
workId: work._id,
|
||||
})
|
||||
);
|
||||
});
|
||||
return EffectArray.sortWith(
|
||||
notices,
|
||||
(notice) => notice.createdAt,
|
||||
Order.Number
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const projectWorkNotices = (input: unknown): readonly WorkNotice[] =>
|
||||
Effect.runSync(projectWorkNoticesEffect(input));
|
||||
Reference in New Issue
Block a user