@xfey/tutti 0.1.14 → 0.1.16
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/collaboration-state/index.d.ts +2 -2
- package/dist/collaboration-state/index.js +1 -1
- package/dist/collaboration-state/scratchpad.d.ts +2 -2
- package/dist/collaboration-state/scratchpad.js +94 -7
- package/dist/collaboration-state/storage-types.d.ts +14 -0
- package/dist/collaboration-state/types.d.ts +9 -1
- package/dist/control-plane/task-compile-output.js +7 -3
- package/dist/control-plane/task-compile-start.js +1 -1
- package/dist/control-plane/workflows/openai.d.ts +1 -0
- package/dist/control-plane/workflows/openai.js +5 -0
- package/dist/providers/openai/app-server/read-only-procedure.d.ts +1 -0
- package/dist/providers/openai/app-server/read-only-procedure.js +3 -1
- package/dist/providers/openai/app-server/skills.d.ts +2 -2
- package/dist/providers/openai/app-server/skills.js +8 -7
- package/dist/providers/openai/app-server/workspace-write-run.d.ts +1 -0
- package/dist/providers/openai/app-server/workspace-write-run.js +4 -2
- package/dist/providers/openai/chat-assistant.d.ts +1 -0
- package/dist/providers/openai/chat-assistant.js +3 -0
- package/dist/run-pipeline/openai.d.ts +1 -0
- package/dist/run-pipeline/openai.js +2 -0
- package/dist/run-pipeline/task-run-invocation.js +1 -0
- package/dist/server-shell/cli/host-server-runtime.js +16 -1
- package/dist/server-shell/cli/project-identity.d.ts +3 -0
- package/dist/server-shell/cli/project-identity.js +24 -0
- package/dist/server-shell/http/routes/agent-context-shared.d.ts +1 -0
- package/dist/server-shell/http/routes/agent-context-shared.js +4 -0
- package/dist/server-shell/http/routes/agent-context-skills-routes.js +3 -3
- package/dist/server-shell/http/routes/project-api/invalidations.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/invalidations.js +4 -1
- package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.d.ts +14 -1
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +22 -1
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.js +14 -1
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +36 -2
- package/dist/server-shell/http/routes/project-api/payload-validation.d.ts +2 -1
- package/dist/server-shell/http/routes/project-api/payload-validation.js +7 -0
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +22 -1
- package/dist/server-shell/http/routes/project-api/schemas.js +1 -0
- package/dist/server-shell/http/routes/project-api/skills-helpers.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/skills-helpers.js +4 -1
- package/dist/server-shell/http/routes/project-api/skills-routes.js +5 -5
- package/dist/server-shell/http/routes/project-api/system-routes.js +66 -4
- package/dist/server-shell/http/routes/project-api/types.d.ts +2 -0
- package/dist/skills/index.d.ts +7 -6
- package/dist/skills/index.js +18 -21
- package/migrations/0012_scratchpad_receipts.sql +31 -0
- package/migrations/README.md +2 -1
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +2 -2
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +2 -2
- package/node_modules/@tutti/shared/dist/schemas/api/runtime-events.d.ts +14 -1
- package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +7 -2
- package/node_modules/@tutti/shared/dist/schemas/api/work-items.d.ts +24 -1
- package/node_modules/@tutti/shared/dist/schemas/api/work-items.js +15 -1
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.d.ts +46 -2
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.js +15 -0
- package/package.json +1 -1
- package/prompts/prompt-flow-map.md +5 -5
- package/prompts/skills/read-user-skills/SKILL.md +1 -1
- package/web/assets/index-DoZOFmIq.js +29 -0
- package/web/assets/index-mXkNKFjm.css +1 -0
- package/web/index.html +8 -2
- package/web/assets/index-Cm_uyHbH.js +0 -29
- package/web/assets/index-DIQpGeKY.css +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { CollaborationStateCursorError } from "./serialization.js";
|
|
2
2
|
export { createIdleExecutionStatusProjection } from "./execution-status.js";
|
|
3
3
|
export { createMainChatAgentMessage, createMainChatMessage, createMainChatSystemMessage, hasMainChatWorklistFeedbackMessage, readCompletedWorklistFeedbackTaskIds, readMessageProjectionById, readMainChatMessageWindow, readMainChatMessagesAfter, readMainChatMessagesAfterCursor, readMainChatMessagesBeforeCursor, } from "./messages.js";
|
|
4
|
-
export {
|
|
4
|
+
export { createEmptyScratchpadProjection, readScratchpadProjection, submitScratchpadProjection, upsertScratchpadProjection, } from "./scratchpad.js";
|
|
5
5
|
export { advanceScratchpadTaskCompileSourceCursor, markScratchpadRefreshFailed, markScratchpadRefreshStarted, markScratchpadRefreshSucceeded, markScratchpadSourceDirty, readScratchpadSourceState, } from "./scratchpad-source-state.js";
|
|
6
6
|
export { deleteStaleClarificationSubmitReplayHints, readActiveClarificationProjection, readClarificationRoundProjection, readClarificationRoundsForThread, readClarificationThreadResponse, readSealedClarificationRoundsWithoutSuccessor, readSubmittedTaskCompileClarificationRounds, readSubmittedTaskCompileClarificationRoundsAfterCursor, } from "./clarification-records.js";
|
|
7
7
|
export { createClarificationRoundAgentMessage, createClarificationRoundMessage, readClarificationRoundMessagesWindow, } from "./clarification-messages.js";
|
|
@@ -13,5 +13,5 @@ export { recoverStaleRunningTasksAsFailed } from "./recovery.js";
|
|
|
13
13
|
export { markReadStateScope, readReadStateSummary, recordReadNotificationEvent, } from "./read-state.js";
|
|
14
14
|
export { readTaskDetailProjection } from "./task-details.js";
|
|
15
15
|
export { applyTaskCompileProposal, markTaskRunStarted, readNextRunnableTask, readRecoverableScheduledRun, readTaskProjection, readWorklistProjection, } from "./worklist.js";
|
|
16
|
-
export type { ApplyTaskCompileProposalResult, CloseTaskBoundClarificationRetaskingRequiredInput, CloseTaskBoundClarificationRetaskingRequiredResult, CreateClarificationRoundAgentMessageInput, CreateClarificationRoundMessageInput, CreateMainChatAgentMessageInput, CreateMainChatMessageInput, CreateMainChatSystemMessageInput, CursorPageOptions, MarkReadStateScopeInput, MarkReadStateScopeResult, MarkTaskRunStartedInput, MarkTaskRunStartedResult, MaterializeClarificationSuccessorInput, MaterializeTaskBoundRunSuccessorInput, MaterializeTaskBoundRunSuccessorResult, MessageAuthorInput, NextRunnableTaskResult, OpenNextTaskBoundClarificationRoundInput, OpenNextTaskBoundClarificationRoundResult, OpenNextTaskCompileClarificationRoundInput, OpenNextTaskCompileClarificationRoundResult, OpenTaskCompileClarificationRoundInput, OpenTaskCompileClarificationRoundResult, ReadMainChatMessagesAfterOptions, ReadMessageWindowOptions, ReadReadStateSummaryInput, RecoverStaleRunningTasksResult, RecoverableScheduledRun, RecordReadNotificationEventInput, RecordRecoverySummaryInput, RecordRecoverySummaryResult, RecordRunNeedsHumanResultInput, RecordRunNeedsHumanResultResult, RecordRunResultInput, RecordRunResultResult, RunResultPromotionProjection, ScratchpadSnapshotInput, SealedClarificationRoundWithoutSuccessor, SubmitClarificationRoundInput, TaskCompileProposalInput, TaskCompileProposalModuleInput, TaskCompileProposalTaskInput, } from "./types.js";
|
|
16
|
+
export type { ApplyTaskCompileProposalResult, CloseTaskBoundClarificationRetaskingRequiredInput, CloseTaskBoundClarificationRetaskingRequiredResult, CreateClarificationRoundAgentMessageInput, CreateClarificationRoundMessageInput, CreateMainChatAgentMessageInput, CreateMainChatMessageInput, CreateMainChatSystemMessageInput, CursorPageOptions, MarkReadStateScopeInput, MarkReadStateScopeResult, MarkTaskRunStartedInput, MarkTaskRunStartedResult, MaterializeClarificationSuccessorInput, MaterializeTaskBoundRunSuccessorInput, MaterializeTaskBoundRunSuccessorResult, MessageAuthorInput, NextRunnableTaskResult, OpenNextTaskBoundClarificationRoundInput, OpenNextTaskBoundClarificationRoundResult, OpenNextTaskCompileClarificationRoundInput, OpenNextTaskCompileClarificationRoundResult, OpenTaskCompileClarificationRoundInput, OpenTaskCompileClarificationRoundResult, ReadMainChatMessagesAfterOptions, ReadMessageWindowOptions, ReadReadStateSummaryInput, RecoverStaleRunningTasksResult, RecoverableScheduledRun, RecordReadNotificationEventInput, RecordRecoverySummaryInput, RecordRecoverySummaryResult, RecordRunNeedsHumanResultInput, RecordRunNeedsHumanResultResult, RecordRunResultInput, RecordRunResultResult, RunResultPromotionProjection, ScratchpadSnapshotInput, SubmitScratchpadInput, SubmitScratchpadResult, SealedClarificationRoundWithoutSuccessor, SubmitClarificationRoundInput, TaskCompileProposalInput, TaskCompileProposalModuleInput, TaskCompileProposalTaskInput, } from "./types.js";
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { CollaborationStateCursorError } from "./serialization.js";
|
|
2
2
|
export { createIdleExecutionStatusProjection } from "./execution-status.js";
|
|
3
3
|
export { createMainChatAgentMessage, createMainChatMessage, createMainChatSystemMessage, hasMainChatWorklistFeedbackMessage, readCompletedWorklistFeedbackTaskIds, readMessageProjectionById, readMainChatMessageWindow, readMainChatMessagesAfter, readMainChatMessagesAfterCursor, readMainChatMessagesBeforeCursor, } from "./messages.js";
|
|
4
|
-
export {
|
|
4
|
+
export { createEmptyScratchpadProjection, readScratchpadProjection, submitScratchpadProjection, upsertScratchpadProjection, } from "./scratchpad.js";
|
|
5
5
|
export { advanceScratchpadTaskCompileSourceCursor, markScratchpadRefreshFailed, markScratchpadRefreshStarted, markScratchpadRefreshSucceeded, markScratchpadSourceDirty, readScratchpadSourceState, } from "./scratchpad-source-state.js";
|
|
6
6
|
export { deleteStaleClarificationSubmitReplayHints, readActiveClarificationProjection, readClarificationRoundProjection, readClarificationRoundsForThread, readClarificationThreadResponse, readSealedClarificationRoundsWithoutSuccessor, readSubmittedTaskCompileClarificationRounds, readSubmittedTaskCompileClarificationRoundsAfterCursor, } from "./clarification-records.js";
|
|
7
7
|
export { createClarificationRoundAgentMessage, createClarificationRoundMessage, readClarificationRoundMessagesWindow, } from "./clarification-messages.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ScratchpadProjection } from "@tutti/shared/schemas/api";
|
|
2
2
|
import type { SqliteDatabase } from "../store/index.js";
|
|
3
|
-
import type { ScratchpadSnapshotInput } from "./types.js";
|
|
3
|
+
import type { ScratchpadSnapshotInput, SubmitScratchpadInput } from "./types.js";
|
|
4
4
|
export declare function createEmptyScratchpadProjection(): ScratchpadProjection;
|
|
5
5
|
export declare function upsertScratchpadProjection(db: SqliteDatabase, input: ScratchpadSnapshotInput): ScratchpadProjection;
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function submitScratchpadProjection(db: SqliteDatabase, input: SubmitScratchpadInput): ScratchpadProjection;
|
|
7
7
|
export declare function readScratchpadProjection(db: SqliteDatabase): ScratchpadProjection;
|
|
8
8
|
//# sourceMappingURL=scratchpad.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { nowIso, parseJson, stringifyJson } from "./serialization.js";
|
|
2
|
+
const SCRATCHPAD_RECEIPT_LIMIT = 100;
|
|
2
3
|
export function createEmptyScratchpadProjection() {
|
|
3
4
|
return {
|
|
4
5
|
id: "current",
|
|
@@ -8,8 +9,37 @@ export function createEmptyScratchpadProjection() {
|
|
|
8
9
|
current_consensus: [],
|
|
9
10
|
open_questions: [],
|
|
10
11
|
task_changes: [],
|
|
12
|
+
receipts: [],
|
|
11
13
|
};
|
|
12
14
|
}
|
|
15
|
+
function readScratchpadReceipts(db) {
|
|
16
|
+
const rows = db
|
|
17
|
+
.prepare(`
|
|
18
|
+
SELECT
|
|
19
|
+
workflow_ref,
|
|
20
|
+
activity_ref,
|
|
21
|
+
topic,
|
|
22
|
+
background_summary,
|
|
23
|
+
current_consensus_json,
|
|
24
|
+
open_questions_json,
|
|
25
|
+
task_changes_json,
|
|
26
|
+
submitted_at
|
|
27
|
+
FROM scratchpad_receipts
|
|
28
|
+
ORDER BY submitted_at DESC, workflow_ref DESC
|
|
29
|
+
LIMIT ${SCRATCHPAD_RECEIPT_LIMIT}
|
|
30
|
+
`)
|
|
31
|
+
.all();
|
|
32
|
+
return rows.map((row) => ({
|
|
33
|
+
workflow_ref: row.workflow_ref,
|
|
34
|
+
activity_ref: row.activity_ref,
|
|
35
|
+
topic: row.topic,
|
|
36
|
+
background_summary: row.background_summary,
|
|
37
|
+
current_consensus: parseJson(row.current_consensus_json, []),
|
|
38
|
+
open_questions: parseJson(row.open_questions_json, []),
|
|
39
|
+
task_changes: parseJson(row.task_changes_json, []),
|
|
40
|
+
submitted_at: row.submitted_at,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
13
43
|
export function upsertScratchpadProjection(db, input) {
|
|
14
44
|
const updatedAt = nowIso(input.now);
|
|
15
45
|
db.prepare(`
|
|
@@ -34,51 +64,108 @@ export function upsertScratchpadProjection(db, input) {
|
|
|
34
64
|
?
|
|
35
65
|
)
|
|
36
66
|
ON CONFLICT(id) DO UPDATE SET
|
|
67
|
+
state = 'ready',
|
|
37
68
|
topic = excluded.topic,
|
|
38
69
|
background_summary = excluded.background_summary,
|
|
39
70
|
current_consensus_json = excluded.current_consensus_json,
|
|
40
71
|
open_questions_json = excluded.open_questions_json,
|
|
41
72
|
task_changes_json = excluded.task_changes_json,
|
|
42
73
|
updated_by_activity_ref = excluded.updated_by_activity_ref,
|
|
43
|
-
updated_at = excluded.updated_at
|
|
74
|
+
updated_at = excluded.updated_at,
|
|
75
|
+
submitted_by_activity_ref = NULL,
|
|
76
|
+
submitted_by_workflow_ref = NULL,
|
|
77
|
+
submitted_at = NULL
|
|
44
78
|
`).run(input.topic, input.background_summary, stringifyJson(input.current_consensus), stringifyJson(input.open_questions), stringifyJson(input.task_changes), input.updated_by_activity_ref ?? null, updatedAt);
|
|
45
79
|
return readScratchpadProjection(db);
|
|
46
80
|
}
|
|
47
|
-
export function
|
|
48
|
-
|
|
49
|
-
|
|
81
|
+
export function submitScratchpadProjection(db, input) {
|
|
82
|
+
const submittedAt = nowIso(input.now);
|
|
83
|
+
const scratchpad = readScratchpadProjection(db);
|
|
84
|
+
if (scratchpad.state === "empty") {
|
|
85
|
+
return scratchpad;
|
|
86
|
+
}
|
|
87
|
+
db.prepare(`
|
|
88
|
+
INSERT INTO scratchpad_receipts (
|
|
89
|
+
workflow_ref,
|
|
90
|
+
activity_ref,
|
|
91
|
+
topic,
|
|
92
|
+
background_summary,
|
|
93
|
+
current_consensus_json,
|
|
94
|
+
open_questions_json,
|
|
95
|
+
task_changes_json,
|
|
96
|
+
submitted_at
|
|
97
|
+
)
|
|
98
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
99
|
+
ON CONFLICT(workflow_ref) DO UPDATE SET
|
|
100
|
+
activity_ref = excluded.activity_ref,
|
|
101
|
+
topic = excluded.topic,
|
|
102
|
+
background_summary = excluded.background_summary,
|
|
103
|
+
current_consensus_json = excluded.current_consensus_json,
|
|
104
|
+
open_questions_json = excluded.open_questions_json,
|
|
105
|
+
task_changes_json = excluded.task_changes_json,
|
|
106
|
+
submitted_at = excluded.submitted_at
|
|
107
|
+
`).run(input.workflow_ref, input.activity_ref, scratchpad.topic, scratchpad.background_summary, stringifyJson(scratchpad.current_consensus), stringifyJson(scratchpad.open_questions), stringifyJson(scratchpad.task_changes), submittedAt);
|
|
108
|
+
db.prepare(`
|
|
109
|
+
UPDATE scratchpad
|
|
110
|
+
SET
|
|
111
|
+
state = 'submitted',
|
|
112
|
+
submitted_by_activity_ref = ?,
|
|
113
|
+
submitted_by_workflow_ref = ?,
|
|
114
|
+
submitted_at = ?,
|
|
115
|
+
updated_at = ?
|
|
116
|
+
WHERE id = 'current'
|
|
117
|
+
`).run(input.activity_ref, input.workflow_ref, submittedAt, submittedAt);
|
|
118
|
+
return readScratchpadProjection(db);
|
|
50
119
|
}
|
|
51
120
|
export function readScratchpadProjection(db) {
|
|
121
|
+
const receipts = readScratchpadReceipts(db);
|
|
52
122
|
const row = db
|
|
53
123
|
.prepare(`
|
|
54
124
|
SELECT
|
|
125
|
+
state,
|
|
55
126
|
topic,
|
|
56
127
|
background_summary,
|
|
57
128
|
current_consensus_json,
|
|
58
129
|
open_questions_json,
|
|
59
130
|
task_changes_json,
|
|
60
131
|
updated_by_activity_ref,
|
|
61
|
-
updated_at
|
|
132
|
+
updated_at,
|
|
133
|
+
submitted_by_activity_ref,
|
|
134
|
+
submitted_by_workflow_ref,
|
|
135
|
+
submitted_at
|
|
62
136
|
FROM scratchpad
|
|
63
137
|
WHERE id = 'current'
|
|
64
138
|
`)
|
|
65
139
|
.get();
|
|
66
140
|
if (row === undefined) {
|
|
67
|
-
return
|
|
141
|
+
return {
|
|
142
|
+
...createEmptyScratchpadProjection(),
|
|
143
|
+
receipts,
|
|
144
|
+
};
|
|
68
145
|
}
|
|
69
146
|
const scratchpad = {
|
|
70
147
|
id: "current",
|
|
71
|
-
state:
|
|
148
|
+
state: row.state,
|
|
72
149
|
topic: row.topic,
|
|
73
150
|
background_summary: row.background_summary,
|
|
74
151
|
current_consensus: parseJson(row.current_consensus_json, []),
|
|
75
152
|
open_questions: parseJson(row.open_questions_json, []),
|
|
76
153
|
task_changes: parseJson(row.task_changes_json, []),
|
|
77
154
|
updated_at: row.updated_at,
|
|
155
|
+
receipts,
|
|
78
156
|
};
|
|
79
157
|
if (row.updated_by_activity_ref !== null) {
|
|
80
158
|
scratchpad.updated_by_activity_ref = row.updated_by_activity_ref;
|
|
81
159
|
}
|
|
160
|
+
if (row.submitted_by_activity_ref !== null) {
|
|
161
|
+
scratchpad.submitted_by_activity_ref = row.submitted_by_activity_ref;
|
|
162
|
+
}
|
|
163
|
+
if (row.submitted_by_workflow_ref !== null) {
|
|
164
|
+
scratchpad.submitted_by_workflow_ref = row.submitted_by_workflow_ref;
|
|
165
|
+
}
|
|
166
|
+
if (row.submitted_at !== null) {
|
|
167
|
+
scratchpad.submitted_at = row.submitted_at;
|
|
168
|
+
}
|
|
82
169
|
return scratchpad;
|
|
83
170
|
}
|
|
84
171
|
//# sourceMappingURL=scratchpad.js.map
|
|
@@ -13,6 +13,7 @@ export type MessageRow = {
|
|
|
13
13
|
created_at: string;
|
|
14
14
|
};
|
|
15
15
|
export type ScratchpadRow = {
|
|
16
|
+
state: "ready" | "submitted";
|
|
16
17
|
topic: string;
|
|
17
18
|
background_summary: string;
|
|
18
19
|
current_consensus_json: string;
|
|
@@ -20,6 +21,19 @@ export type ScratchpadRow = {
|
|
|
20
21
|
task_changes_json: string;
|
|
21
22
|
updated_by_activity_ref: string | null;
|
|
22
23
|
updated_at: string;
|
|
24
|
+
submitted_by_activity_ref: string | null;
|
|
25
|
+
submitted_by_workflow_ref: string | null;
|
|
26
|
+
submitted_at: string | null;
|
|
27
|
+
};
|
|
28
|
+
export type ScratchpadReceiptRow = {
|
|
29
|
+
workflow_ref: string;
|
|
30
|
+
activity_ref: string;
|
|
31
|
+
topic: string;
|
|
32
|
+
background_summary: string;
|
|
33
|
+
current_consensus_json: string;
|
|
34
|
+
open_questions_json: string;
|
|
35
|
+
task_changes_json: string;
|
|
36
|
+
submitted_at: string;
|
|
23
37
|
};
|
|
24
38
|
export type ScratchpadSourceStateRow = {
|
|
25
39
|
main_chat_cursor_created_at: string | null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RunLineage } from "@tutti/shared/domain";
|
|
2
2
|
import type { AccountAvatarProjection } from "@tutti/shared/domain";
|
|
3
3
|
import type { ActivityRef, ClarificationRoundRef, TaskId, TaskModuleId, WorkflowInvocationRef } from "@tutti/shared/ids";
|
|
4
|
-
import type { ClarificationRequestPayload, ClarificationRoundProjection, ClarificationSuccessorRef, ClarificationThreadProjection, MessageProjection, ReadStateScope, ReadStateSummaryProjection, RecoverySummaryProjection, RunResultProjection, TaskContractProjection, TaskDetailProjection, TaskDetailResultProjection, TaskProjection, WorklistProjection } from "@tutti/shared/schemas/api";
|
|
4
|
+
import type { ClarificationRequestPayload, ClarificationRoundProjection, ClarificationSuccessorRef, ClarificationThreadProjection, MessageProjection, ReadStateScope, ReadStateSummaryProjection, RecoverySummaryProjection, RunResultProjection, ScratchpadProjection, TaskContractProjection, TaskDetailProjection, TaskDetailResultProjection, TaskProjection, WorklistProjection } from "@tutti/shared/schemas/api";
|
|
5
5
|
export type MessageAuthorInput = {
|
|
6
6
|
kind: "human" | "system" | "agent";
|
|
7
7
|
ref?: string;
|
|
@@ -56,6 +56,14 @@ export type ScratchpadSnapshotInput = {
|
|
|
56
56
|
updated_by_activity_ref?: ActivityRef;
|
|
57
57
|
now?: () => Date;
|
|
58
58
|
};
|
|
59
|
+
export type SubmitScratchpadInput = {
|
|
60
|
+
workflow_ref: WorkflowInvocationRef;
|
|
61
|
+
activity_ref: ActivityRef;
|
|
62
|
+
now?: () => Date;
|
|
63
|
+
};
|
|
64
|
+
export type SubmitScratchpadResult = {
|
|
65
|
+
scratchpad: ScratchpadProjection;
|
|
66
|
+
};
|
|
59
67
|
export type TaskCompileProposalInput = {
|
|
60
68
|
workflow_ref: WorkflowInvocationRef;
|
|
61
69
|
proposal: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { applyTaskCompileProposal,
|
|
1
|
+
import { applyTaskCompileProposal, openNextTaskCompileClarificationRound, openTaskCompileClarificationRound, readWorklistProjection, submitScratchpadProjection, } from "../collaboration-state/index.js";
|
|
2
2
|
import { clarificationInvalidates, taskCompileInvalidates, } from "./invalidations.js";
|
|
3
3
|
import { normalizeTaskCompileProposal } from "./task-proposal.js";
|
|
4
4
|
const EMPTY_INITIAL_WORKLIST_CLARIFICATION = {
|
|
@@ -86,7 +86,11 @@ export function applyTaskCompileProcedureOutput(input) {
|
|
|
86
86
|
if (applied.changed_task_ids.length > 0) {
|
|
87
87
|
input.onTasksAdded?.();
|
|
88
88
|
}
|
|
89
|
-
const
|
|
89
|
+
const submittedScratchpad = submitScratchpadProjection(input.store.db, {
|
|
90
|
+
workflow_ref: input.workflowRef,
|
|
91
|
+
activity_ref: input.activityRef,
|
|
92
|
+
now: input.now,
|
|
93
|
+
});
|
|
90
94
|
input.events.publish({
|
|
91
95
|
event_type: "worklist.changed",
|
|
92
96
|
payload: {
|
|
@@ -101,7 +105,7 @@ export function applyTaskCompileProcedureOutput(input) {
|
|
|
101
105
|
input.events.publish({
|
|
102
106
|
event_type: "scratchpad.updated",
|
|
103
107
|
payload: {
|
|
104
|
-
scratchpad:
|
|
108
|
+
scratchpad: submittedScratchpad,
|
|
105
109
|
activity_ref: input.activityRef,
|
|
106
110
|
},
|
|
107
111
|
invalidates: taskCompileInvalidates(),
|
|
@@ -51,7 +51,7 @@ export function startControlPlaneTaskCompile(options) {
|
|
|
51
51
|
sourceBatch,
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
-
if (scratchpad.state
|
|
54
|
+
if (scratchpad.state !== "ready") {
|
|
55
55
|
return { disposition: { kind: "scratchpad_empty" } };
|
|
56
56
|
}
|
|
57
57
|
if (shouldInitializeProjectContext) {
|
|
@@ -7,6 +7,7 @@ import { readOpenAiApiKeyCredential } from "../../providers/openai/credential-st
|
|
|
7
7
|
import { resolveOpenAiProviderConfig, } from "../../providers/openai/provider-config.js";
|
|
8
8
|
import { SCRATCHPAD_REFRESH_OUTPUT_SCHEMA, TASK_COMPILE_OUTPUT_SCHEMA, PROJECT_CONTEXT_BOOTSTRAP_OUTPUT_SCHEMA, CONTEXT_SYNC_OUTPUT_SCHEMA, PROJECT_BRIEF_REFRESH_OUTPUT_SCHEMA, FOLLOW_UP_CHECK_OUTPUT_SCHEMA, REFERENCE_FILE_SUMMARY_OUTPUT_SCHEMA, isContextSyncWorkflowOutput, isFollowUpCheckStructuredOutput, isProjectBriefRefreshWorkflowOutput, isProjectContextBootstrapWorkflowOutput, isReferenceFileSummaryStructuredOutput, isScratchpadRefreshStructuredOutput, isTaskCompileStructuredOutput, } from "./structured-output.js";
|
|
9
9
|
import { runCodexAppServerReadOnlyProcedure } from "../../providers/openai/app-server/read-only-procedure.js";
|
|
10
|
+
import { getProjectUserSkillsRoot } from "../../skills/index.js";
|
|
10
11
|
function readOnlyAppServerOptions(options, prompt, outputSchema, skillSelectionName) {
|
|
11
12
|
if (options.readOnlyAppServer === undefined) {
|
|
12
13
|
throw new Error("Codex app-server read-only Procedure adapter is not configured");
|
|
@@ -36,6 +37,9 @@ function readOnlyAppServerOptions(options, prompt, outputSchema, skillSelectionN
|
|
|
36
37
|
...(options.readOnlyAppServer.tuttiHome === undefined
|
|
37
38
|
? {}
|
|
38
39
|
: { tuttiHome: options.readOnlyAppServer.tuttiHome }),
|
|
40
|
+
...(options.readOnlyAppServer.userSkillsRoot === undefined
|
|
41
|
+
? {}
|
|
42
|
+
: { userSkillsRoot: options.readOnlyAppServer.userSkillsRoot }),
|
|
39
43
|
...(options.readOnlyAppServer.builtInSkillsRoot === undefined
|
|
40
44
|
? {}
|
|
41
45
|
: { builtInSkillsRoot: options.readOnlyAppServer.builtInSkillsRoot }),
|
|
@@ -421,6 +425,7 @@ export function resolveProjectOpenAiProcedureWorkflowRunner(options) {
|
|
|
421
425
|
apiKey: credential.secret,
|
|
422
426
|
workspaceRoot: options.workspaceRoot,
|
|
423
427
|
tuttiHome: options.tuttiHome,
|
|
428
|
+
userSkillsRoot: getProjectUserSkillsRoot(options.tuttiHome, options.projectId),
|
|
424
429
|
...(options.agentContext === undefined ? {} : { agentContext: options.agentContext }),
|
|
425
430
|
},
|
|
426
431
|
...(options.recordUsage === undefined ? {} : { recordUsage: options.recordUsage }),
|
|
@@ -16,6 +16,7 @@ export type CodexAppServerReadOnlyProcedureInput<TOutput> = {
|
|
|
16
16
|
webSearchMode?: CodexAppServerWebSearchMode;
|
|
17
17
|
skillSelectionName?: CodexAppServerSkillSelectionName;
|
|
18
18
|
tuttiHome?: string;
|
|
19
|
+
userSkillsRoot?: string;
|
|
19
20
|
builtInSkillsRoot?: string;
|
|
20
21
|
agentContext?: CodexAppServerAgentContextRuntime;
|
|
21
22
|
strictLeakCheck?: boolean;
|
|
@@ -81,7 +81,7 @@ export async function runCodexAppServerReadOnlyProcedure(options) {
|
|
|
81
81
|
try {
|
|
82
82
|
skillInputs = resolveCodexAppServerSkillInputs({
|
|
83
83
|
...(options.skillSelectionName === undefined ? {} : { selectionName: options.skillSelectionName }),
|
|
84
|
-
...(options.
|
|
84
|
+
...(options.userSkillsRoot === undefined ? {} : { userSkillsRoot: options.userSkillsRoot }),
|
|
85
85
|
...(options.builtInSkillsRoot === undefined
|
|
86
86
|
? {}
|
|
87
87
|
: { builtInSkillsRoot: options.builtInSkillsRoot }),
|
|
@@ -100,6 +100,7 @@ export async function runCodexAppServerReadOnlyProcedure(options) {
|
|
|
100
100
|
options.workspaceRoot,
|
|
101
101
|
options.appServerCwd ?? "",
|
|
102
102
|
options.tuttiHome ?? "",
|
|
103
|
+
options.userSkillsRoot ?? "",
|
|
103
104
|
options.builtInSkillsRoot ?? "",
|
|
104
105
|
]));
|
|
105
106
|
}
|
|
@@ -145,6 +146,7 @@ export async function runCodexAppServerReadOnlyProcedure(options) {
|
|
|
145
146
|
appServerCwd,
|
|
146
147
|
...readablePaths,
|
|
147
148
|
options.tuttiHome ?? "",
|
|
149
|
+
options.userSkillsRoot ?? "",
|
|
148
150
|
options.builtInSkillsRoot ?? "",
|
|
149
151
|
...(contextRuntimeHint?.sensitiveValues ?? []),
|
|
150
152
|
...skillInputs.map((skill) => skill.path),
|
|
@@ -56,13 +56,13 @@ export declare function resolveCodexAppServerSkillInputs(options: {
|
|
|
56
56
|
selectionName?: CodexAppServerSkillSelectionName;
|
|
57
57
|
selection?: CodexAppServerSkillSelection;
|
|
58
58
|
builtInSkillsRoot?: string;
|
|
59
|
-
|
|
59
|
+
userSkillsRoot?: string;
|
|
60
60
|
}): CodexAppServerSkillInput[];
|
|
61
61
|
export declare function resolveCodexAppServerSkillsListWarmup(options: {
|
|
62
62
|
cwd: string;
|
|
63
63
|
selectionName?: CodexAppServerSkillSelectionName;
|
|
64
64
|
selection?: CodexAppServerSkillSelection;
|
|
65
|
-
|
|
65
|
+
userSkillsRoot?: string;
|
|
66
66
|
}): CodexAppServerSkillsListWarmup | undefined;
|
|
67
67
|
export declare function buildCodexAppServerTurnInput(options: {
|
|
68
68
|
prompt: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, statSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import {
|
|
4
|
+
import { listUserSkills } from "../../../skills/index.js";
|
|
5
5
|
export class CodexAppServerSkillSelectionError extends Error {
|
|
6
6
|
code;
|
|
7
7
|
constructor(code, message) {
|
|
@@ -117,7 +117,7 @@ function resolveBuiltInSkill(options) {
|
|
|
117
117
|
function resolveUserSkill(options) {
|
|
118
118
|
return {
|
|
119
119
|
name: options.name,
|
|
120
|
-
path: join(
|
|
120
|
+
path: join(options.userSkillsRoot, options.name),
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
export function resolveCodexAppServerSkillSelection(selectionName) {
|
|
@@ -134,8 +134,9 @@ export function resolveCodexAppServerSkillInputs(options) {
|
|
|
134
134
|
: resolveCodexAppServerSkillSelection(options.selectionName));
|
|
135
135
|
const builtInSkillsRoot = options.builtInSkillsRoot ?? DEFAULT_BUILT_IN_SKILLS_ROOT;
|
|
136
136
|
const builtInSkills = selection.builtInSkillNames.map((name) => resolveBuiltInSkill({ builtInSkillsRoot, name }));
|
|
137
|
-
const
|
|
138
|
-
|
|
137
|
+
const userSkillsRoot = options.userSkillsRoot;
|
|
138
|
+
const userSkills = selection.userSkillMode === "all_enabled" && userSkillsRoot !== undefined
|
|
139
|
+
? listUserSkills(userSkillsRoot).map((skill) => resolveUserSkill({ userSkillsRoot, name: skill.name }))
|
|
139
140
|
: [];
|
|
140
141
|
return [...builtInSkills, ...userSkills];
|
|
141
142
|
}
|
|
@@ -148,10 +149,10 @@ export function resolveCodexAppServerSkillsListWarmup(options) {
|
|
|
148
149
|
contextApiScopes: [],
|
|
149
150
|
}
|
|
150
151
|
: resolveCodexAppServerSkillSelection(options.selectionName));
|
|
151
|
-
if (selection.userSkillMode !== "all_enabled" || options.
|
|
152
|
+
if (selection.userSkillMode !== "all_enabled" || options.userSkillsRoot === undefined) {
|
|
152
153
|
return undefined;
|
|
153
154
|
}
|
|
154
|
-
if (listUserSkills(options.
|
|
155
|
+
if (listUserSkills(options.userSkillsRoot).length === 0) {
|
|
155
156
|
return undefined;
|
|
156
157
|
}
|
|
157
158
|
return {
|
|
@@ -160,7 +161,7 @@ export function resolveCodexAppServerSkillsListWarmup(options) {
|
|
|
160
161
|
perCwdExtraUserRoots: [
|
|
161
162
|
{
|
|
162
163
|
cwd: options.cwd,
|
|
163
|
-
extraUserRoots: [
|
|
164
|
+
extraUserRoots: [options.userSkillsRoot],
|
|
164
165
|
},
|
|
165
166
|
],
|
|
166
167
|
};
|
|
@@ -40,6 +40,7 @@ export type CodexAppServerWorkspaceWriteRunInput<TOutput> = {
|
|
|
40
40
|
approvalsReviewer?: CodexAppServerApprovalsReviewer;
|
|
41
41
|
skillSelectionName?: CodexAppServerSkillSelectionName;
|
|
42
42
|
tuttiHome?: string;
|
|
43
|
+
userSkillsRoot?: string;
|
|
43
44
|
builtInSkillsRoot?: string;
|
|
44
45
|
agentContext?: CodexAppServerAgentContextRuntime;
|
|
45
46
|
approvalHandler?: CodexAppServerApprovalHandler;
|
|
@@ -153,7 +153,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
153
153
|
try {
|
|
154
154
|
skillInputs = resolveCodexAppServerSkillInputs({
|
|
155
155
|
...(options.skillSelectionName === undefined ? {} : { selectionName: options.skillSelectionName }),
|
|
156
|
-
...(options.
|
|
156
|
+
...(options.userSkillsRoot === undefined ? {} : { userSkillsRoot: options.userSkillsRoot }),
|
|
157
157
|
...(options.builtInSkillsRoot === undefined
|
|
158
158
|
? {}
|
|
159
159
|
: { builtInSkillsRoot: options.builtInSkillsRoot }),
|
|
@@ -161,7 +161,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
161
161
|
skillsListWarmup = resolveCodexAppServerSkillsListWarmup({
|
|
162
162
|
cwd: options.workspaceRoot,
|
|
163
163
|
...(options.skillSelectionName === undefined ? {} : { selectionName: options.skillSelectionName }),
|
|
164
|
-
...(options.
|
|
164
|
+
...(options.userSkillsRoot === undefined ? {} : { userSkillsRoot: options.userSkillsRoot }),
|
|
165
165
|
});
|
|
166
166
|
contextRuntimeHint = resolveCodexAppServerContextRuntimeHint({
|
|
167
167
|
...(options.skillSelectionName === undefined ? {} : { selectionName: options.skillSelectionName }),
|
|
@@ -176,6 +176,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
176
176
|
options.apiKey,
|
|
177
177
|
options.workspaceRoot,
|
|
178
178
|
options.tuttiHome ?? "",
|
|
179
|
+
options.userSkillsRoot ?? "",
|
|
179
180
|
options.builtInSkillsRoot ?? "",
|
|
180
181
|
]));
|
|
181
182
|
}
|
|
@@ -219,6 +220,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
219
220
|
codexHome,
|
|
220
221
|
options.workspaceRoot,
|
|
221
222
|
options.tuttiHome ?? "",
|
|
223
|
+
options.userSkillsRoot ?? "",
|
|
222
224
|
options.builtInSkillsRoot ?? "",
|
|
223
225
|
...(contextRuntimeHint?.sensitiveValues ?? []),
|
|
224
226
|
...skillInputs.map((skill) => skill.path),
|
|
@@ -2,6 +2,7 @@ import { CHAT_ASSISTANT_OUTPUT_SCHEMA, isChatAssistantOutput, } from "../../chat
|
|
|
2
2
|
import { readOpenAiApiKeyCredential } from "./credential-store.js";
|
|
3
3
|
import { resolveOpenAiProviderConfig, } from "./provider-config.js";
|
|
4
4
|
import { runCodexAppServerReadOnlyProcedure } from "./app-server/read-only-procedure.js";
|
|
5
|
+
import { getProjectUserSkillsRoot } from "../../skills/index.js";
|
|
5
6
|
export function createOpenAiReadOnlyChatAssistantModel(options) {
|
|
6
7
|
return {
|
|
7
8
|
async answer(input) {
|
|
@@ -19,6 +20,7 @@ export function createOpenAiReadOnlyChatAssistantModel(options) {
|
|
|
19
20
|
webSearchMode: "live",
|
|
20
21
|
skillSelectionName: "chat_assistant",
|
|
21
22
|
...(options.tuttiHome === undefined ? {} : { tuttiHome: options.tuttiHome }),
|
|
23
|
+
...(options.userSkillsRoot === undefined ? {} : { userSkillsRoot: options.userSkillsRoot }),
|
|
22
24
|
...(options.builtInSkillsRoot === undefined
|
|
23
25
|
? {}
|
|
24
26
|
: { builtInSkillsRoot: options.builtInSkillsRoot }),
|
|
@@ -60,6 +62,7 @@ export function resolveProjectOpenAiReadOnlyChatAssistantModel(options) {
|
|
|
60
62
|
apiKey: credential.secret,
|
|
61
63
|
workspaceRoot: options.workspaceRoot,
|
|
62
64
|
tuttiHome: options.tuttiHome,
|
|
65
|
+
userSkillsRoot: getProjectUserSkillsRoot(options.tuttiHome, options.projectId),
|
|
63
66
|
...(options.agentContext === undefined ? {} : { agentContext: options.agentContext }),
|
|
64
67
|
...(options.recordUsage === undefined ? {} : { recordUsage: options.recordUsage }),
|
|
65
68
|
}),
|
|
@@ -13,6 +13,7 @@ export type OpenAiRunPipelineRunnerOptions = {
|
|
|
13
13
|
mergeWorkspaceRoot?: string;
|
|
14
14
|
promptsRoot?: string;
|
|
15
15
|
tuttiHome?: string;
|
|
16
|
+
userSkillsRoot?: string;
|
|
16
17
|
builtInSkillsRoot?: string;
|
|
17
18
|
agentContext?: CodexAppServerAgentContextRuntime;
|
|
18
19
|
approvalManager?: ApprovalRequestManager;
|
|
@@ -7,6 +7,7 @@ import { runWorkspaceWriteTask } from "./task-run-invocation.js";
|
|
|
7
7
|
import { readOpenAiApiKeyCredential } from "../providers/openai/credential-store.js";
|
|
8
8
|
import { resolveOpenAiProviderConfig, } from "../providers/openai/provider-config.js";
|
|
9
9
|
import { CodexAppServerWorkspaceWriteRunError } from "../providers/openai/app-server/workspace-write-run.js";
|
|
10
|
+
import { getProjectUserSkillsRoot } from "../skills/index.js";
|
|
10
11
|
import { cleanupRunWorkspace, collectRunDiff, createResultCommit, prepareRunWorkspace, promoteRunResult, WorkspaceOpsError, } from "../workspace-ops/index.js";
|
|
11
12
|
export { TASK_RUN_OUTPUT_SCHEMA } from "./task-run-output.js";
|
|
12
13
|
function isRecord(value) {
|
|
@@ -535,6 +536,7 @@ export function resolveProjectOpenAiRunPipelineRunner(options) {
|
|
|
535
536
|
runWorkspaceRoot: join(options.runWorkspaceRoot, "run-workspaces"),
|
|
536
537
|
mergeWorkspaceRoot: join(options.mergeWorkspaceRoot ?? options.runWorkspaceRoot, "merge-workspaces"),
|
|
537
538
|
tuttiHome: options.tuttiHome,
|
|
539
|
+
userSkillsRoot: getProjectUserSkillsRoot(options.tuttiHome, options.projectId),
|
|
538
540
|
...(options.agentContext === undefined ? {} : { agentContext: options.agentContext }),
|
|
539
541
|
...(options.approvalManager === undefined
|
|
540
542
|
? {}
|
|
@@ -99,6 +99,7 @@ export async function runWorkspaceWriteTask(options, input, handle) {
|
|
|
99
99
|
? {}
|
|
100
100
|
: { apiBaseUrl: options.config.api_base_url }),
|
|
101
101
|
...(options.tuttiHome === undefined ? {} : { tuttiHome: options.tuttiHome }),
|
|
102
|
+
...(options.userSkillsRoot === undefined ? {} : { userSkillsRoot: options.userSkillsRoot }),
|
|
102
103
|
...(options.builtInSkillsRoot === undefined
|
|
103
104
|
? {}
|
|
104
105
|
: { builtInSkillsRoot: options.builtInSkillsRoot }),
|
|
@@ -21,7 +21,7 @@ import { createTrustedRelaySessionMetadataStore, } from "../session/relay-sessio
|
|
|
21
21
|
import { LaunchError } from "./errors.js";
|
|
22
22
|
import { relayStateFromLaunchStatus } from "./host-relay-status.js";
|
|
23
23
|
import { appendHostLogLine, readHostRegistrationSecret, createMachineRuntimeEndpointToken, deleteMachineRuntimeEndpoint, ensureHostLogFile, getHostLogFilePath, writeMachineRuntimeEndpoint, } from "./machine-local.js";
|
|
24
|
-
import { readProjectDisplayName, writeProjectDisplayName } from "./project-identity.js";
|
|
24
|
+
import { readProjectDescription, readProjectDisplayName, writeProjectDescription, writeProjectDisplayName, } from "./project-identity.js";
|
|
25
25
|
export const HOST_SERVER_VERSION = "0.0.0";
|
|
26
26
|
function createHostRuntimeLogger(options) {
|
|
27
27
|
return {
|
|
@@ -163,6 +163,7 @@ export async function startForegroundHostServer(options) {
|
|
|
163
163
|
};
|
|
164
164
|
let projectDisplayName = readProjectDisplayName(options.preparation.workspace_root) ??
|
|
165
165
|
(basename(options.preparation.workspace_root) || options.preparation.project_id);
|
|
166
|
+
let projectDescription = readProjectDescription(options.preparation.workspace_root) ?? "";
|
|
166
167
|
const projectContext = {
|
|
167
168
|
workspaceRoot: options.preparation.workspace_root,
|
|
168
169
|
projectName: projectDisplayName,
|
|
@@ -174,6 +175,7 @@ export async function startForegroundHostServer(options) {
|
|
|
174
175
|
const projectApiProject = {
|
|
175
176
|
project_id: options.preparation.project_id,
|
|
176
177
|
display_name: projectDisplayName,
|
|
178
|
+
...(projectDescription.length === 0 ? {} : { description: projectDescription }),
|
|
177
179
|
identity_source: "git_config",
|
|
178
180
|
};
|
|
179
181
|
const updateRuntimeProjectDisplayName = (displayName) => {
|
|
@@ -183,6 +185,16 @@ export async function startForegroundHostServer(options) {
|
|
|
183
185
|
chatAssistantProject.display_name = displayName;
|
|
184
186
|
projectApiProject.display_name = displayName;
|
|
185
187
|
};
|
|
188
|
+
const updateRuntimeProjectDescription = (description) => {
|
|
189
|
+
writeProjectDescription(options.preparation.workspace_root, description);
|
|
190
|
+
projectDescription = description;
|
|
191
|
+
if (description.length === 0) {
|
|
192
|
+
delete projectApiProject.description;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
projectApiProject.description = description;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
186
198
|
const controlPlaneLogger = createHostRuntimeLogger({
|
|
187
199
|
component: "control-plane",
|
|
188
200
|
logFilePath,
|
|
@@ -353,6 +365,9 @@ export async function startForegroundHostServer(options) {
|
|
|
353
365
|
updateProjectDisplayName: (displayName) => {
|
|
354
366
|
updateRuntimeProjectDisplayName(displayName);
|
|
355
367
|
},
|
|
368
|
+
updateProjectDescription: (description) => {
|
|
369
|
+
updateRuntimeProjectDescription(description);
|
|
370
|
+
},
|
|
356
371
|
...(resolveStagedUpload === undefined ? {} : { resolveStagedUpload }),
|
|
357
372
|
capabilities: {
|
|
358
373
|
clarification: true,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ProjectId } from "@tutti/shared/ids";
|
|
2
2
|
export declare const PROJECT_ID_GIT_CONFIG_KEY = "tutti.project-id";
|
|
3
3
|
export declare const PROJECT_DISPLAY_NAME_GIT_CONFIG_KEY = "tutti.project-display-name";
|
|
4
|
+
export declare const PROJECT_DESCRIPTION_GIT_CONFIG_KEY = "tutti.project-description";
|
|
4
5
|
export type ProjectIdentityReadResult = {
|
|
5
6
|
kind: "missing";
|
|
6
7
|
} | {
|
|
@@ -12,6 +13,8 @@ export declare function readProjectIdentity(workspaceRoot: string): ProjectIdent
|
|
|
12
13
|
export declare function writeProjectIdentity(workspaceRoot: string, projectId: ProjectId): void;
|
|
13
14
|
export declare function readProjectDisplayName(workspaceRoot: string): string | null;
|
|
14
15
|
export declare function writeProjectDisplayName(workspaceRoot: string, displayName: string): void;
|
|
16
|
+
export declare function readProjectDescription(workspaceRoot: string): string | null;
|
|
17
|
+
export declare function writeProjectDescription(workspaceRoot: string, description: string): void;
|
|
15
18
|
export declare function ensureProjectIdentity(workspaceRoot: string, projectId?: ProjectId): {
|
|
16
19
|
project_id: ProjectId;
|
|
17
20
|
created: boolean;
|