@xfey/tutti 0.1.97 → 0.1.99
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/README.md +2 -1
- package/dist/artifact-feedback/index.d.ts +19 -0
- package/dist/artifact-feedback/index.js +196 -0
- package/dist/chat-assistant/index.js +5 -4
- package/dist/collaboration-state/task-compile-context.d.ts +1 -1
- package/dist/control-plane/index.js +15 -3
- package/dist/control-plane/scratchpad-source-messages.js +2 -1
- package/dist/control-plane/task-source-context.js +3 -2
- package/dist/control-plane/worklist-terminal-feedback.js +4 -4
- package/dist/server-shell/http/routes/agent-context-references.js +8 -14
- package/dist/server-shell/http/routes/project-api/artifacts-routes.d.ts +2 -1
- package/dist/server-shell/http/routes/project-api/artifacts-routes.js +1 -0
- package/dist/server-shell/http/routes/project-api/messages-routes.d.ts +3 -1
- package/dist/server-shell/http/routes/project-api/messages-routes.js +61 -29
- package/dist/server-shell/http/routes/project-api/openapi-viewer-routes.d.ts +0 -2
- package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +8 -2
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +8 -2
- package/dist/server-shell/http/routes/project-api/payload-validation.js +12 -0
- package/dist/server-shell/http/routes/project-api/reference-files.js +6 -17
- package/dist/server-shell/http/routes/project-api/schemas.d.ts +8 -2
- package/dist/server-shell/http/routes/project-api/schemas.js +2 -0
- package/dist/server-shell/http/routes/project-api/types.d.ts +1 -0
- package/dist/server-shell/http/routes/project-api/workspace-projections.js +1 -0
- package/dist/server-shell/http/routes/project-api.js +2 -2
- package/dist/workspace-ops/constants.d.ts +0 -1
- package/dist/workspace-ops/constants.js +0 -1
- package/dist/workspace-ops/index.d.ts +3 -2
- package/dist/workspace-ops/index.js +3 -2
- package/dist/workspace-ops/project-doc-templates.js +1 -1
- package/dist/workspace-ops/reference-files.js +3 -2
- package/dist/workspace-ops/reference-metadata.d.ts +2 -2
- package/dist/workspace-ops/reference-metadata.js +8 -22
- package/dist/workspace-ops/reference-summaries.js +11 -17
- package/dist/workspace-ops/reference-tree.d.ts +11 -0
- package/dist/workspace-ops/reference-tree.js +34 -0
- package/dist/workspace-ops/viewer-git.d.ts +1 -0
- package/dist/workspace-ops/viewer-git.js +11 -0
- package/node_modules/@tutti/shared/dist/schemas/api/artifact-feedback.d.ts +374 -0
- package/node_modules/@tutti/shared/dist/schemas/api/artifact-feedback.js +83 -0
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.d.ts +86 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +2 -1
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +2 -1
- package/node_modules/@tutti/shared/dist/schemas/api/messages.d.ts +441 -2
- package/node_modules/@tutti/shared/dist/schemas/api/messages.js +17 -3
- package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +13 -1
- package/node_modules/@tutti/shared/dist/schemas/api/viewer-reference.d.ts +86 -5
- package/node_modules/@tutti/shared/dist/schemas/api/viewer-reference.js +0 -2
- package/package.json +1 -1
- package/prompts/procedures/context-sync.md +3 -3
- package/prompts/procedures/reference-file-summary.md +1 -1
- package/prompts/procedures/task-compile.md +2 -2
- package/prompts/prompt-flow-map.md +1 -1
- package/prompts/runs/task-execute.md +2 -2
- package/prompts/skills/read-references/SKILL.md +2 -2
- package/web/assets/homepage-motion-scene-BtMS4SCZ.js +1 -0
- package/web/assets/index-DtZ_5QLQ.js +69 -0
- package/web/assets/index-JY06YzFV.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/homepage-motion-scene-lpr-1FjJ.js +0 -1
- package/web/assets/index-CQoq2PtU.js +0 -69
- package/web/assets/index-quWLFJgD.css +0 -1
|
@@ -585,7 +585,7 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
585
585
|
};
|
|
586
586
|
readonly capabilities: {
|
|
587
587
|
readonly type: "object";
|
|
588
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
588
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification", "artifact_feedback"];
|
|
589
589
|
readonly additionalProperties: false;
|
|
590
590
|
readonly properties: {
|
|
591
591
|
readonly sse: {
|
|
@@ -616,6 +616,9 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
616
616
|
readonly clarification: {
|
|
617
617
|
readonly type: "boolean";
|
|
618
618
|
};
|
|
619
|
+
readonly artifact_feedback: {
|
|
620
|
+
readonly type: "boolean";
|
|
621
|
+
};
|
|
619
622
|
};
|
|
620
623
|
};
|
|
621
624
|
};
|
|
@@ -776,7 +779,7 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
776
779
|
};
|
|
777
780
|
readonly capabilities: {
|
|
778
781
|
readonly type: "object";
|
|
779
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
782
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification", "artifact_feedback"];
|
|
780
783
|
readonly additionalProperties: false;
|
|
781
784
|
readonly properties: {
|
|
782
785
|
readonly sse: {
|
|
@@ -807,6 +810,9 @@ export declare const HOST_PROJECT_WORKSPACE_OPENAPI_ROUTES: ({
|
|
|
807
810
|
readonly clarification: {
|
|
808
811
|
readonly type: "boolean";
|
|
809
812
|
};
|
|
813
|
+
readonly artifact_feedback: {
|
|
814
|
+
readonly type: "boolean";
|
|
815
|
+
};
|
|
810
816
|
};
|
|
811
817
|
};
|
|
812
818
|
};
|
|
@@ -1868,7 +1868,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
1868
1868
|
};
|
|
1869
1869
|
readonly capabilities: {
|
|
1870
1870
|
readonly type: "object";
|
|
1871
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
1871
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification", "artifact_feedback"];
|
|
1872
1872
|
readonly additionalProperties: false;
|
|
1873
1873
|
readonly properties: {
|
|
1874
1874
|
readonly sse: {
|
|
@@ -1899,6 +1899,9 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
1899
1899
|
readonly clarification: {
|
|
1900
1900
|
readonly type: "boolean";
|
|
1901
1901
|
};
|
|
1902
|
+
readonly artifact_feedback: {
|
|
1903
|
+
readonly type: "boolean";
|
|
1904
|
+
};
|
|
1902
1905
|
};
|
|
1903
1906
|
};
|
|
1904
1907
|
};
|
|
@@ -2059,7 +2062,7 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
2059
2062
|
};
|
|
2060
2063
|
readonly capabilities: {
|
|
2061
2064
|
readonly type: "object";
|
|
2062
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
2065
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification", "artifact_feedback"];
|
|
2063
2066
|
readonly additionalProperties: false;
|
|
2064
2067
|
readonly properties: {
|
|
2065
2068
|
readonly sse: {
|
|
@@ -2090,6 +2093,9 @@ export declare const HOST_PROJECT_OPENAPI_ROUTES: ({
|
|
|
2090
2093
|
readonly clarification: {
|
|
2091
2094
|
readonly type: "boolean";
|
|
2092
2095
|
};
|
|
2096
|
+
readonly artifact_feedback: {
|
|
2097
|
+
readonly type: "boolean";
|
|
2098
|
+
};
|
|
2093
2099
|
};
|
|
2094
2100
|
};
|
|
2095
2101
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ArtifactFeedbackValidationError, normalizeArtifactFeedbackCommand, } from "../../../../artifact-feedback/index.js";
|
|
1
2
|
import { HostProjectBadRequestError, HostProjectValidationError } from "./errors.js";
|
|
2
3
|
export function requireValidMessageWindowRequest(query) {
|
|
3
4
|
if (query.before !== undefined && query.after !== undefined) {
|
|
@@ -9,6 +10,17 @@ export function requireValidMessageWindowRequest(query) {
|
|
|
9
10
|
return query;
|
|
10
11
|
}
|
|
11
12
|
export function requireValidSendMainChatPayload(payload) {
|
|
13
|
+
if ("artifact_feedback" in payload) {
|
|
14
|
+
try {
|
|
15
|
+
return { artifact_feedback: normalizeArtifactFeedbackCommand(payload.artifact_feedback) };
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof ArtifactFeedbackValidationError) {
|
|
19
|
+
throw new HostProjectValidationError(error.message);
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
12
24
|
if (payload.body.trim() === "") {
|
|
13
25
|
throw new HostProjectValidationError("Message body cannot be empty");
|
|
14
26
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH,
|
|
1
|
+
import { REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH, VIEWER_HARD_READ_LIMIT_BYTES, WorkspaceOpsError, readReferenceFileEntries, readReferenceSummaryIndex, readViewerFile, readViewerSnapshot, referenceFileCategoryForPath, referenceMediaTypeForPath, referenceSummaryProjectionForEntry, } from "../../../../workspace-ops/index.js";
|
|
2
2
|
import { paginateViewerItems, viewerPageLimit } from "./viewer-projections.js";
|
|
3
3
|
function unreadableReasonForReferenceContent(content) {
|
|
4
4
|
if (content.kind === "text") {
|
|
@@ -34,7 +34,6 @@ export function toReferenceFileProjection(options) {
|
|
|
34
34
|
path: options.entry.path,
|
|
35
35
|
name: options.entry.name,
|
|
36
36
|
category,
|
|
37
|
-
source: referenceFileSourceForPath(options.entry.path) ?? "human_upload",
|
|
38
37
|
size_bytes: options.entry.size_bytes ?? 0,
|
|
39
38
|
text_read: referenceTextReadProjection(options.workspaceRoot, options.entry, options.now),
|
|
40
39
|
summary: referenceSummaryProjectionForEntry({
|
|
@@ -65,7 +64,6 @@ function referenceDirectoryProjection(options) {
|
|
|
65
64
|
index_path: REFERENCE_INDEX_PATH,
|
|
66
65
|
files_path: REFERENCE_FILES_DIRECTORY_PATH,
|
|
67
66
|
images_path: REFERENCE_IMAGES_DIRECTORY_PATH,
|
|
68
|
-
tutti_path: REFERENCE_TUTTI_DIRECTORY_PATH,
|
|
69
67
|
index_status: "missing",
|
|
70
68
|
};
|
|
71
69
|
}
|
|
@@ -82,7 +80,6 @@ function referenceDirectoryProjection(options) {
|
|
|
82
80
|
index_path: REFERENCE_INDEX_PATH,
|
|
83
81
|
files_path: REFERENCE_FILES_DIRECTORY_PATH,
|
|
84
82
|
images_path: REFERENCE_IMAGES_DIRECTORY_PATH,
|
|
85
|
-
tutti_path: REFERENCE_TUTTI_DIRECTORY_PATH,
|
|
86
83
|
index_status: "available",
|
|
87
84
|
};
|
|
88
85
|
}
|
|
@@ -92,7 +89,6 @@ function referenceDirectoryProjection(options) {
|
|
|
92
89
|
index_path: REFERENCE_INDEX_PATH,
|
|
93
90
|
files_path: REFERENCE_FILES_DIRECTORY_PATH,
|
|
94
91
|
images_path: REFERENCE_IMAGES_DIRECTORY_PATH,
|
|
95
|
-
tutti_path: REFERENCE_TUTTI_DIRECTORY_PATH,
|
|
96
92
|
index_status: "unreadable",
|
|
97
93
|
index_unreadable_reason: file.content.reason,
|
|
98
94
|
};
|
|
@@ -105,7 +101,6 @@ function referenceDirectoryProjection(options) {
|
|
|
105
101
|
index_path: REFERENCE_INDEX_PATH,
|
|
106
102
|
files_path: REFERENCE_FILES_DIRECTORY_PATH,
|
|
107
103
|
images_path: REFERENCE_IMAGES_DIRECTORY_PATH,
|
|
108
|
-
tutti_path: REFERENCE_TUTTI_DIRECTORY_PATH,
|
|
109
104
|
index_status: "missing",
|
|
110
105
|
};
|
|
111
106
|
}
|
|
@@ -119,14 +114,9 @@ export function readReferenceFilesResponse(options, query) {
|
|
|
119
114
|
workspaceRoot,
|
|
120
115
|
...(now === undefined ? {} : { now }),
|
|
121
116
|
});
|
|
122
|
-
let
|
|
117
|
+
let entries;
|
|
123
118
|
try {
|
|
124
|
-
|
|
125
|
-
workspaceRoot,
|
|
126
|
-
path: REFERENCE_DIRECTORY_PATH,
|
|
127
|
-
depth: 3,
|
|
128
|
-
...(now === undefined ? {} : { now }),
|
|
129
|
-
});
|
|
119
|
+
entries = readReferenceFileEntries({ workspaceRoot });
|
|
130
120
|
}
|
|
131
121
|
catch (error) {
|
|
132
122
|
if (error instanceof WorkspaceOpsError && error.code === "not_found") {
|
|
@@ -148,11 +138,10 @@ export function readReferenceFilesResponse(options, query) {
|
|
|
148
138
|
}
|
|
149
139
|
const includeIndex = query.include_index ?? false;
|
|
150
140
|
const summaryIndex = readReferenceSummaryIndex({ workspaceRoot });
|
|
151
|
-
const referenceItems =
|
|
152
|
-
.filter((entry) => entry.kind === "file")
|
|
141
|
+
const referenceItems = entries
|
|
153
142
|
.filter((entry) => includeIndex || entry.path !== REFERENCE_INDEX_PATH)
|
|
154
143
|
.filter((entry) => entry.path === REFERENCE_INDEX_PATH ||
|
|
155
|
-
|
|
144
|
+
referenceFileCategoryForPath(entry.path) !== undefined)
|
|
156
145
|
.sort((left, right) => {
|
|
157
146
|
const leftCategory = referenceFileCategoryForPath(left.path) ?? "file";
|
|
158
147
|
const rightCategory = referenceFileCategoryForPath(right.path) ?? "file";
|
|
@@ -202,7 +191,7 @@ export function referenceFileMessageRef(file) {
|
|
|
202
191
|
const ref = {
|
|
203
192
|
path: file.path,
|
|
204
193
|
name: file.name,
|
|
205
|
-
source:
|
|
194
|
+
source: "human_upload",
|
|
206
195
|
category: file.category,
|
|
207
196
|
size_bytes: file.size_bytes,
|
|
208
197
|
text_read: file.text_read,
|
|
@@ -560,7 +560,7 @@ export declare const WorkspaceResponseSchema: {
|
|
|
560
560
|
};
|
|
561
561
|
readonly capabilities: {
|
|
562
562
|
readonly type: "object";
|
|
563
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
563
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification", "artifact_feedback"];
|
|
564
564
|
readonly additionalProperties: false;
|
|
565
565
|
readonly properties: {
|
|
566
566
|
readonly sse: {
|
|
@@ -591,6 +591,9 @@ export declare const WorkspaceResponseSchema: {
|
|
|
591
591
|
readonly clarification: {
|
|
592
592
|
readonly type: "boolean";
|
|
593
593
|
};
|
|
594
|
+
readonly artifact_feedback: {
|
|
595
|
+
readonly type: "boolean";
|
|
596
|
+
};
|
|
594
597
|
};
|
|
595
598
|
};
|
|
596
599
|
};
|
|
@@ -740,7 +743,7 @@ export declare const BootstrapResponseSchema: {
|
|
|
740
743
|
};
|
|
741
744
|
readonly capabilities: {
|
|
742
745
|
readonly type: "object";
|
|
743
|
-
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification"];
|
|
746
|
+
readonly required: readonly ["sse", "relay_join", "repo_viewer", "provider_config_query", "provider_model_update", "browser_secret_write", "task_auto_scheduler", "task_run_now_scheduler", "clarification", "artifact_feedback"];
|
|
744
747
|
readonly additionalProperties: false;
|
|
745
748
|
readonly properties: {
|
|
746
749
|
readonly sse: {
|
|
@@ -771,6 +774,9 @@ export declare const BootstrapResponseSchema: {
|
|
|
771
774
|
readonly clarification: {
|
|
772
775
|
readonly type: "boolean";
|
|
773
776
|
};
|
|
777
|
+
readonly artifact_feedback: {
|
|
778
|
+
readonly type: "boolean";
|
|
779
|
+
};
|
|
774
780
|
};
|
|
775
781
|
};
|
|
776
782
|
};
|
|
@@ -316,6 +316,7 @@ export const WorkspaceResponseSchema = {
|
|
|
316
316
|
"task_auto_scheduler",
|
|
317
317
|
"task_run_now_scheduler",
|
|
318
318
|
"clarification",
|
|
319
|
+
"artifact_feedback",
|
|
319
320
|
],
|
|
320
321
|
additionalProperties: false,
|
|
321
322
|
properties: {
|
|
@@ -328,6 +329,7 @@ export const WorkspaceResponseSchema = {
|
|
|
328
329
|
task_auto_scheduler: { type: "boolean" },
|
|
329
330
|
task_run_now_scheduler: { type: "boolean" },
|
|
330
331
|
clarification: { type: "boolean" },
|
|
332
|
+
artifact_feedback: { type: "boolean" },
|
|
331
333
|
},
|
|
332
334
|
},
|
|
333
335
|
},
|
|
@@ -72,6 +72,7 @@ export type HostProjectApiCapabilities = {
|
|
|
72
72
|
task_auto_scheduler: boolean;
|
|
73
73
|
task_run_now_scheduler: boolean;
|
|
74
74
|
clarification: boolean;
|
|
75
|
+
artifact_feedback: boolean;
|
|
75
76
|
};
|
|
76
77
|
export type HostProviderModelService = {
|
|
77
78
|
discover: () => Promise<GetProviderModelsResponse>;
|
|
@@ -13,6 +13,7 @@ function defaultCapabilities(options) {
|
|
|
13
13
|
task_auto_scheduler: overrides?.task_auto_scheduler ?? false,
|
|
14
14
|
task_run_now_scheduler: overrides?.task_run_now_scheduler ?? true,
|
|
15
15
|
clarification: overrides?.clarification ?? false,
|
|
16
|
+
artifact_feedback: overrides?.artifact_feedback ?? true,
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
function providerSummary(providerConfig) {
|
|
@@ -23,8 +23,8 @@ export function registerHostProjectApiRoutes(app, options) {
|
|
|
23
23
|
registerViewerRoutes(app, options);
|
|
24
24
|
registerReferenceFilesRoutes(app, { options, workspaceEvents });
|
|
25
25
|
registerSkillRoutes(app, { options, workspaceEvents });
|
|
26
|
-
registerArtifactsRoutes(app, { options, workspaceEvents });
|
|
27
|
-
registerMessagesRoutes(app, { options, workspaceEvents });
|
|
26
|
+
const artifactPreviewManager = registerArtifactsRoutes(app, { options, workspaceEvents });
|
|
27
|
+
registerMessagesRoutes(app, { options, workspaceEvents, artifactPreviewManager });
|
|
28
28
|
registerWorkflowRoutes(app, options);
|
|
29
29
|
registerReadStateRoutes(app, { options, workspaceEvents });
|
|
30
30
|
registerClarificationRoutes(app, options);
|
|
@@ -5,7 +5,6 @@ export declare const VIEWER_HARD_READ_LIMIT_BYTES: number;
|
|
|
5
5
|
export declare const REFERENCE_DIRECTORY_PATH: "docs/reference";
|
|
6
6
|
export declare const REFERENCE_FILES_DIRECTORY_PATH: "docs/reference/files";
|
|
7
7
|
export declare const REFERENCE_IMAGES_DIRECTORY_PATH: "docs/reference/images";
|
|
8
|
-
export declare const REFERENCE_TUTTI_DIRECTORY_PATH: "docs/reference/tutti";
|
|
9
8
|
export declare const REFERENCE_INDEX_PATH: "docs/reference/README.md";
|
|
10
9
|
export declare const MAX_REFERENCE_UPLOAD_BYTES: number;
|
|
11
10
|
export declare const VIEWER_ASSET_READ_LIMIT_BYTES: number;
|
|
@@ -5,7 +5,6 @@ export const VIEWER_HARD_READ_LIMIT_BYTES = 5 * 1024 * 1024;
|
|
|
5
5
|
export const REFERENCE_DIRECTORY_PATH = "docs/reference";
|
|
6
6
|
export const REFERENCE_FILES_DIRECTORY_PATH = "docs/reference/files";
|
|
7
7
|
export const REFERENCE_IMAGES_DIRECTORY_PATH = "docs/reference/images";
|
|
8
|
-
export const REFERENCE_TUTTI_DIRECTORY_PATH = "docs/reference/tutti";
|
|
9
8
|
export const REFERENCE_INDEX_PATH = "docs/reference/README.md";
|
|
10
9
|
export const MAX_REFERENCE_UPLOAD_BYTES = 10 * 1024 * 1024;
|
|
11
10
|
export const VIEWER_ASSET_READ_LIMIT_BYTES = MAX_REFERENCE_UPLOAD_BYTES;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export { DEFAULT_VIEWER_MAX_BYTES, MAX_REFERENCE_UPLOAD_BYTES, MAX_VIEWER_MAX_BYTES, PROJECT_DOC_PATHS, REFERENCE_IMAGE_ASSET_CACHE_VERSION, REFERENCE_IMAGE_PREVIEW_MAX_EDGE_PX, REFERENCE_IMAGE_THUMBNAIL_MAX_EDGE_PX, REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH,
|
|
1
|
+
export { DEFAULT_VIEWER_MAX_BYTES, MAX_REFERENCE_UPLOAD_BYTES, MAX_VIEWER_MAX_BYTES, PROJECT_DOC_PATHS, REFERENCE_IMAGE_ASSET_CACHE_VERSION, REFERENCE_IMAGE_PREVIEW_MAX_EDGE_PX, REFERENCE_IMAGE_THUMBNAIL_MAX_EDGE_PX, REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH, VIEWER_ASSET_READ_LIMIT_BYTES, VIEWER_HARD_READ_LIMIT_BYTES, WORKSPACE_OPS_MAINLINE_BRANCH, } from "./constants.js";
|
|
2
2
|
export { WorkspaceOpsError } from "./errors.js";
|
|
3
3
|
export { commitOwnedPaths, requireOwnedPathsWriteReady } from "./system-commits.js";
|
|
4
4
|
export { collectProjectSourceDiff, createAcceptedCheckpoint, inspectProjectWorkspace, recoverAcceptedCheckpoint, } from "./project-workspace.js";
|
|
5
5
|
export { initializeProjectDocs, readProjectDocsInitializationStatus, syncProjectDocs, } from "./project-docs.js";
|
|
6
6
|
export { uploadReferenceFile } from "./reference-files.js";
|
|
7
|
-
export { referenceFileCategoryForPath,
|
|
7
|
+
export { isReferenceFilePath, referenceFileCategoryForPath, referenceFolderGroupForPath, referenceMediaTypeForPath, } from "./reference-metadata.js";
|
|
8
|
+
export { readReferenceFileEntries } from "./reference-tree.js";
|
|
8
9
|
export { readReferenceSummaryEntries, readReferenceSummaryIndex, readReferenceSummaryTargets, referenceSummaryProjectionForEntry, updateReferenceSummaries, } from "./reference-summaries.js";
|
|
9
10
|
export { readViewerAsset, readViewerFile, readViewerSnapshot, readViewerTree } from "./viewer.js";
|
|
10
11
|
export type { WorkspaceOpsErrorCode } from "./errors.js";
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export { DEFAULT_VIEWER_MAX_BYTES, MAX_REFERENCE_UPLOAD_BYTES, MAX_VIEWER_MAX_BYTES, PROJECT_DOC_PATHS, REFERENCE_IMAGE_ASSET_CACHE_VERSION, REFERENCE_IMAGE_PREVIEW_MAX_EDGE_PX, REFERENCE_IMAGE_THUMBNAIL_MAX_EDGE_PX, REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH,
|
|
1
|
+
export { DEFAULT_VIEWER_MAX_BYTES, MAX_REFERENCE_UPLOAD_BYTES, MAX_VIEWER_MAX_BYTES, PROJECT_DOC_PATHS, REFERENCE_IMAGE_ASSET_CACHE_VERSION, REFERENCE_IMAGE_PREVIEW_MAX_EDGE_PX, REFERENCE_IMAGE_THUMBNAIL_MAX_EDGE_PX, REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH, VIEWER_ASSET_READ_LIMIT_BYTES, VIEWER_HARD_READ_LIMIT_BYTES, WORKSPACE_OPS_MAINLINE_BRANCH, } from "./constants.js";
|
|
2
2
|
export { WorkspaceOpsError } from "./errors.js";
|
|
3
3
|
export { commitOwnedPaths, requireOwnedPathsWriteReady } from "./system-commits.js";
|
|
4
4
|
export { collectProjectSourceDiff, createAcceptedCheckpoint, inspectProjectWorkspace, recoverAcceptedCheckpoint, } from "./project-workspace.js";
|
|
5
5
|
export { initializeProjectDocs, readProjectDocsInitializationStatus, syncProjectDocs, } from "./project-docs.js";
|
|
6
6
|
export { uploadReferenceFile } from "./reference-files.js";
|
|
7
|
-
export { referenceFileCategoryForPath,
|
|
7
|
+
export { isReferenceFilePath, referenceFileCategoryForPath, referenceFolderGroupForPath, referenceMediaTypeForPath, } from "./reference-metadata.js";
|
|
8
|
+
export { readReferenceFileEntries } from "./reference-tree.js";
|
|
8
9
|
export { readReferenceSummaryEntries, readReferenceSummaryIndex, readReferenceSummaryTargets, referenceSummaryProjectionForEntry, updateReferenceSummaries, } from "./reference-summaries.js";
|
|
9
10
|
export { readViewerAsset, readViewerFile, readViewerSnapshot, readViewerTree } from "./viewer.js";
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -129,7 +129,7 @@ ${asBulletList([
|
|
|
129
129
|
...repoHints.directories.map((directory) => `Top-level directory: \`${directory}/\``),
|
|
130
130
|
...repoHints.root_files.map((file) => `Root file: \`${file}\``),
|
|
131
131
|
], "Repository structure is pending context sync.")}
|
|
132
|
-
-
|
|
132
|
+
- Shared reference materials maintained by project members and Tutti, when present, live under \`docs/reference/\`.
|
|
133
133
|
|
|
134
134
|
## Naming Conventions
|
|
135
135
|
|
|
@@ -110,7 +110,7 @@ function appendReferenceIndexEntry(options) {
|
|
|
110
110
|
? [
|
|
111
111
|
"# Reference Files",
|
|
112
112
|
"",
|
|
113
|
-
"
|
|
113
|
+
"Shared project reference files maintained by project members and Tutti.",
|
|
114
114
|
"",
|
|
115
115
|
"## Files",
|
|
116
116
|
"",
|
|
@@ -185,7 +185,8 @@ export function uploadReferenceFile(options) {
|
|
|
185
185
|
paths: [REFERENCE_INDEX_PATH, repoPath],
|
|
186
186
|
message: `Add reference file: ${safeName}`,
|
|
187
187
|
});
|
|
188
|
-
const resolvedCommitOid = commitOid ??
|
|
188
|
+
const resolvedCommitOid = commitOid ??
|
|
189
|
+
readViewerFile({ workspaceRoot: options.workspaceRoot, path: repoPath }).snapshot.head.oid;
|
|
189
190
|
const file = readViewerFile({
|
|
190
191
|
workspaceRoot: options.workspaceRoot,
|
|
191
192
|
path: repoPath,
|
|
@@ -9,7 +9,7 @@ export declare function classifyReferenceUpload(options: {
|
|
|
9
9
|
directoryPath: string;
|
|
10
10
|
};
|
|
11
11
|
export declare function referenceFileCategoryForPath(path: string): ReferenceFileCategory | undefined;
|
|
12
|
-
export declare function
|
|
13
|
-
export declare function
|
|
12
|
+
export declare function isReferenceFilePath(path: string): boolean;
|
|
13
|
+
export declare function referenceFolderGroupForPath(path: string): string | undefined;
|
|
14
14
|
export declare function referenceMediaTypeForPath(path: string): string | undefined;
|
|
15
15
|
//# sourceMappingURL=reference-metadata.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { extname
|
|
2
|
-
import { REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH,
|
|
1
|
+
import { extname } from "node:path";
|
|
2
|
+
import { REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH, } from "./constants.js";
|
|
3
3
|
const REFERENCE_IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif"]);
|
|
4
4
|
const REFERENCE_IMAGE_MEDIA_TYPES = new Set(["image/png", "image/jpeg", "image/webp", "image/gif"]);
|
|
5
5
|
function normalizeMediaType(mediaType) {
|
|
@@ -54,33 +54,19 @@ export function referenceFileCategoryForPath(path) {
|
|
|
54
54
|
if (path.startsWith(`${REFERENCE_IMAGES_DIRECTORY_PATH}/`)) {
|
|
55
55
|
return "image";
|
|
56
56
|
}
|
|
57
|
-
if (path
|
|
58
|
-
return "file";
|
|
59
|
-
}
|
|
60
|
-
if (path.startsWith(`${REFERENCE_TUTTI_DIRECTORY_PATH}/`)) {
|
|
61
|
-
return "file";
|
|
62
|
-
}
|
|
63
|
-
if (posix.dirname(path) === REFERENCE_DIRECTORY_PATH && path !== REFERENCE_INDEX_PATH) {
|
|
57
|
+
if (isReferenceFilePath(path)) {
|
|
64
58
|
return "file";
|
|
65
59
|
}
|
|
66
60
|
return undefined;
|
|
67
61
|
}
|
|
68
|
-
export function
|
|
69
|
-
|
|
70
|
-
return "tutti_output";
|
|
71
|
-
}
|
|
72
|
-
if (path.startsWith(`${REFERENCE_FILES_DIRECTORY_PATH}/`) ||
|
|
73
|
-
path.startsWith(`${REFERENCE_IMAGES_DIRECTORY_PATH}/`) ||
|
|
74
|
-
(posix.dirname(path) === REFERENCE_DIRECTORY_PATH && path !== REFERENCE_INDEX_PATH)) {
|
|
75
|
-
return "human_upload";
|
|
76
|
-
}
|
|
77
|
-
return undefined;
|
|
62
|
+
export function isReferenceFilePath(path) {
|
|
63
|
+
return path !== REFERENCE_INDEX_PATH && path.startsWith(`${REFERENCE_DIRECTORY_PATH}/`);
|
|
78
64
|
}
|
|
79
|
-
export function
|
|
80
|
-
if (!path
|
|
65
|
+
export function referenceFolderGroupForPath(path) {
|
|
66
|
+
if (!isReferenceFilePath(path)) {
|
|
81
67
|
return undefined;
|
|
82
68
|
}
|
|
83
|
-
const rest = path.slice(
|
|
69
|
+
const rest = path.slice(REFERENCE_DIRECTORY_PATH.length + 1);
|
|
84
70
|
const [first, second] = rest.split("/");
|
|
85
71
|
if (first === undefined || first.length === 0 || second === undefined) {
|
|
86
72
|
return undefined;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { redactText } from "@tutti/shared/utils";
|
|
4
|
-
import {
|
|
4
|
+
import { REFERENCE_INDEX_PATH } from "./constants.js";
|
|
5
5
|
import { referenceFileCategoryForPath, referenceMediaTypeForPath } from "./reference-metadata.js";
|
|
6
|
+
import { readReferenceFileEntries } from "./reference-tree.js";
|
|
6
7
|
import { commitOwnedPaths, requireOwnedPathsWriteReady } from "./system-commits.js";
|
|
7
|
-
import { readViewerTree } from "./viewer.js";
|
|
8
8
|
const SUMMARY_SECTION_HEADING = "## Summaries";
|
|
9
9
|
const SUMMARY_BLOCK_START = "<!-- tutti-reference-summaries:v1";
|
|
10
10
|
const SUMMARY_BLOCK_END = "-->";
|
|
@@ -115,7 +115,7 @@ function readReferenceIndexContent(workspaceRoot) {
|
|
|
115
115
|
return [
|
|
116
116
|
"# Reference Files",
|
|
117
117
|
"",
|
|
118
|
-
"
|
|
118
|
+
"Shared project reference files maintained by project members and Tutti.",
|
|
119
119
|
"",
|
|
120
120
|
"## Files",
|
|
121
121
|
"",
|
|
@@ -138,8 +138,7 @@ export function referenceSummaryProjectionForEntry(options) {
|
|
|
138
138
|
...(record.source_blob_oid === undefined ? {} : { source_blob_oid: record.source_blob_oid }),
|
|
139
139
|
...(record.read_paths === undefined ? {} : { read_paths: record.read_paths }),
|
|
140
140
|
};
|
|
141
|
-
if (options.entry.blob_oid !== undefined &&
|
|
142
|
-
record.source_blob_oid !== options.entry.blob_oid) {
|
|
141
|
+
if (options.entry.blob_oid !== undefined && record.source_blob_oid !== options.entry.blob_oid) {
|
|
143
142
|
return {
|
|
144
143
|
status: "stale",
|
|
145
144
|
...base,
|
|
@@ -165,14 +164,8 @@ export function referenceSummaryProjectionForEntry(options) {
|
|
|
165
164
|
...(record.summary === undefined ? {} : { text: record.summary }),
|
|
166
165
|
};
|
|
167
166
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
workspaceRoot: options.workspaceRoot,
|
|
171
|
-
path: REFERENCE_DIRECTORY_PATH,
|
|
172
|
-
depth: 2,
|
|
173
|
-
...(options.now === undefined ? {} : { now: options.now }),
|
|
174
|
-
});
|
|
175
|
-
return tree.items
|
|
167
|
+
function readSummaryFileEntries(options) {
|
|
168
|
+
return readReferenceFileEntries({ workspaceRoot: options.workspaceRoot })
|
|
176
169
|
.filter((entry) => entry.kind === "file")
|
|
177
170
|
.filter((entry) => referenceFileCategoryForPath(entry.path) !== undefined)
|
|
178
171
|
.filter((entry) => entry.blob_oid !== undefined && entry.size_bytes !== undefined)
|
|
@@ -181,7 +174,7 @@ function readReferenceFileEntries(options) {
|
|
|
181
174
|
export function readReferenceSummaryEntries(options) {
|
|
182
175
|
const summaries = readReferenceSummaryIndex({ workspaceRoot: options.workspaceRoot });
|
|
183
176
|
const requested = options.paths === undefined ? undefined : new Set(options.paths);
|
|
184
|
-
return
|
|
177
|
+
return readSummaryFileEntries(options)
|
|
185
178
|
.filter((entry) => requested === undefined || requested.has(entry.path))
|
|
186
179
|
.map((entry) => {
|
|
187
180
|
const category = referenceFileCategoryForPath(entry.path) ?? "file";
|
|
@@ -239,7 +232,9 @@ function renderSummaryRecord(record) {
|
|
|
239
232
|
return rendered;
|
|
240
233
|
}
|
|
241
234
|
function renderSummariesSection(records) {
|
|
242
|
-
const items = records
|
|
235
|
+
const items = records
|
|
236
|
+
.map(renderSummaryRecord)
|
|
237
|
+
.sort((left, right) => left.path.localeCompare(right.path, "en", { sensitivity: "base" }));
|
|
243
238
|
const json = JSON.stringify({ items }, null, 2);
|
|
244
239
|
const lines = [
|
|
245
240
|
SUMMARY_SECTION_HEADING,
|
|
@@ -277,9 +272,8 @@ export function updateReferenceSummaries(options) {
|
|
|
277
272
|
}
|
|
278
273
|
existing.set(summary.path, rendered);
|
|
279
274
|
}
|
|
280
|
-
const currentPaths = new Set(
|
|
275
|
+
const currentPaths = new Set(readSummaryFileEntries({
|
|
281
276
|
workspaceRoot: options.workspaceRoot,
|
|
282
|
-
...(options.now === undefined ? {} : { now: options.now }),
|
|
283
277
|
}).map((entry) => entry.path));
|
|
284
278
|
const records = [...existing.values()].filter((record) => currentPaths.has(record.path));
|
|
285
279
|
const nextContent = `${removeSummarySection(existingContent)}\n\n${renderSummariesSection(records)}\n`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ViewerTreeEntry } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Enumerate every committed regular file in the shared Reference directory.
|
|
4
|
+
* The generic Repo Viewer intentionally keeps its bounded depth contract; this
|
|
5
|
+
* Reference-specific reader is the single recursive source for the API,
|
|
6
|
+
* summaries, and agent context.
|
|
7
|
+
*/
|
|
8
|
+
export declare function readReferenceFileEntries(options: {
|
|
9
|
+
workspaceRoot: string;
|
|
10
|
+
}): ViewerTreeEntry[];
|
|
11
|
+
//# sourceMappingURL=reference-tree.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
2
|
+
import { REFERENCE_DIRECTORY_PATH } from "./constants.js";
|
|
3
|
+
import { WorkspaceOpsError } from "./errors.js";
|
|
4
|
+
import { entryKind, lsPath, lsTreeRecursive } from "./viewer-git.js";
|
|
5
|
+
import { isPathAllowedForProjection } from "./viewer-paths.js";
|
|
6
|
+
import { createViewerTreeEntry } from "./viewer-tree.js";
|
|
7
|
+
/**
|
|
8
|
+
* Enumerate every committed regular file in the shared Reference directory.
|
|
9
|
+
* The generic Repo Viewer intentionally keeps its bounded depth contract; this
|
|
10
|
+
* Reference-specific reader is the single recursive source for the API,
|
|
11
|
+
* summaries, and agent context.
|
|
12
|
+
*/
|
|
13
|
+
export function readReferenceFileEntries(options) {
|
|
14
|
+
const root = lsPath(options.workspaceRoot, REFERENCE_DIRECTORY_PATH);
|
|
15
|
+
if (root === null) {
|
|
16
|
+
throw new WorkspaceOpsError("not_found", "Reference directory was not found");
|
|
17
|
+
}
|
|
18
|
+
if (entryKind(root) !== "directory") {
|
|
19
|
+
throw new WorkspaceOpsError("validation_failed", "Reference path is not a directory");
|
|
20
|
+
}
|
|
21
|
+
return lsTreeRecursive(options.workspaceRoot, REFERENCE_DIRECTORY_PATH)
|
|
22
|
+
.filter((entry) => entryKind(entry) === "file")
|
|
23
|
+
.filter((entry) => isPathAllowedForProjection(entry.path))
|
|
24
|
+
.map((entry) => {
|
|
25
|
+
const relativePath = entry.path.slice(REFERENCE_DIRECTORY_PATH.length + 1);
|
|
26
|
+
return createViewerTreeEntry(entry, {
|
|
27
|
+
path: entry.path,
|
|
28
|
+
parentPath: posix.dirname(entry.path),
|
|
29
|
+
depth: relativePath.split("/").length,
|
|
30
|
+
});
|
|
31
|
+
})
|
|
32
|
+
.sort((left, right) => left.path.localeCompare(right.path, "en", { sensitivity: "base" }));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=reference-tree.js.map
|
|
@@ -9,6 +9,7 @@ export type RawTreeEntry = {
|
|
|
9
9
|
export declare function readViewerSnapshot(options: WorkspaceViewerOptions): ViewerRepoSnapshot;
|
|
10
10
|
export declare function lsPath(workspaceRoot: string, normalizedPath: string): RawTreeEntry | null;
|
|
11
11
|
export declare function lsDirectoryChildren(workspaceRoot: string, normalizedPath: string): RawTreeEntry[];
|
|
12
|
+
export declare function lsTreeRecursive(workspaceRoot: string, normalizedPath: string): RawTreeEntry[];
|
|
12
13
|
export declare function entryKind(entry: RawTreeEntry): ViewerEntryKind;
|
|
13
14
|
export declare function requireFileEntry(options: {
|
|
14
15
|
workspaceRoot: string;
|
|
@@ -76,6 +76,17 @@ export function lsDirectoryChildren(workspaceRoot, normalizedPath) {
|
|
|
76
76
|
: `${WORKSPACE_OPS_MAINLINE_BRANCH}:${normalizedPath}`;
|
|
77
77
|
return lsTree(workspaceRoot, ["ls-tree", "-z", "-l", treeish]);
|
|
78
78
|
}
|
|
79
|
+
export function lsTreeRecursive(workspaceRoot, normalizedPath) {
|
|
80
|
+
return lsTree(workspaceRoot, [
|
|
81
|
+
"ls-tree",
|
|
82
|
+
"-r",
|
|
83
|
+
"-z",
|
|
84
|
+
"-l",
|
|
85
|
+
WORKSPACE_OPS_MAINLINE_BRANCH,
|
|
86
|
+
"--",
|
|
87
|
+
normalizedPath,
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
79
90
|
export function entryKind(entry) {
|
|
80
91
|
if (entry.mode === "040000" || entry.type === "tree") {
|
|
81
92
|
return "directory";
|