feat: projects as backend sources with system prompt injection (#8739)
Signed-off-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -752,12 +752,24 @@ export type CreateSourceRequest = {
|
||||
* Absolute path to the project root. Required when `global` is false.
|
||||
*/
|
||||
projectDir?: string | null;
|
||||
/**
|
||||
* Project source ID. When set with `global: false`, the backend resolves
|
||||
* the project's first working directory automatically. Takes precedence
|
||||
* over `project_dir`.
|
||||
*/
|
||||
projectId?: string | null;
|
||||
/**
|
||||
* Arbitrary key/value metadata.
|
||||
*/
|
||||
properties?: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of source entity.
|
||||
*/
|
||||
export type SourceType = 'skill' | 'builtinSkill' | 'recipe' | 'subrecipe' | 'agent';
|
||||
export type SourceType = 'skill' | 'builtinSkill' | 'recipe' | 'subrecipe' | 'agent' | 'project';
|
||||
|
||||
export type CreateSourceResponse = {
|
||||
source: SourceEntry;
|
||||
@@ -774,11 +786,12 @@ export type SourceEntry = {
|
||||
description: string;
|
||||
content: string;
|
||||
/**
|
||||
* Absolute path to the source on disk. A directory for skills, a file for
|
||||
* recipes and agents. Built-in skills use read-only synthetic
|
||||
* `builtin://skills/<name>` paths.
|
||||
* Stable on-disk path identifying this source. Pass it back to
|
||||
* update/delete/export to operate on this entry. Skills use the directory
|
||||
* containing `SKILL.md`; projects use the project file path; built-in
|
||||
* skills use `builtin://skills/<name>` synthetic paths.
|
||||
*/
|
||||
directory: string;
|
||||
path: string;
|
||||
/**
|
||||
* True when the source lives in the user's global sources directory; false
|
||||
* when it lives inside a specific project.
|
||||
@@ -789,6 +802,13 @@ export type SourceEntry = {
|
||||
* Only skills currently populate this; empty for other source types.
|
||||
*/
|
||||
supportingFiles?: Array<string>;
|
||||
/**
|
||||
* Arbitrary key/value pairs for type-specific metadata (e.g. icon, color,
|
||||
* preferredProvider for projects). Stored in the frontmatter.
|
||||
*/
|
||||
properties?: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -802,6 +822,11 @@ export type SourceEntry = {
|
||||
export type ListSourcesRequest = {
|
||||
type?: SourceType | null;
|
||||
projectDir?: string | null;
|
||||
/**
|
||||
* When true, also scan the working directories of all known projects for
|
||||
* project-scoped sources (e.g. skills stored under `{workingDir}/.agents/skills/`).
|
||||
*/
|
||||
includeProjectSources?: boolean;
|
||||
};
|
||||
|
||||
export type ListSourcesResponse = {
|
||||
@@ -817,6 +842,16 @@ export type UpdateSourceRequest = {
|
||||
name: string;
|
||||
description: string;
|
||||
content: string;
|
||||
/**
|
||||
* When `Some`, replaces all stored properties on the source. When
|
||||
* `None` (or omitted), the source's existing properties are
|
||||
* preserved. Callers that don't model the full property bag (e.g.
|
||||
* the skills editor, which only edits name/description/content)
|
||||
* should omit this so per-skill metadata isn't silently erased.
|
||||
*/
|
||||
properties?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type UpdateSourceResponse = {
|
||||
|
||||
@@ -755,7 +755,8 @@ export const zSourceType = z.enum([
|
||||
'builtinSkill',
|
||||
'recipe',
|
||||
'subrecipe',
|
||||
'agent'
|
||||
'agent',
|
||||
'project'
|
||||
]);
|
||||
|
||||
/**
|
||||
@@ -770,7 +771,12 @@ export const zCreateSourceRequest = z.object({
|
||||
projectDir: z.union([
|
||||
z.string(),
|
||||
z.null()
|
||||
]).optional()
|
||||
]).optional(),
|
||||
projectId: z.union([
|
||||
z.string(),
|
||||
z.null()
|
||||
]).optional(),
|
||||
properties: z.record(z.unknown()).optional()
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -783,9 +789,10 @@ export const zSourceEntry = z.object({
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
content: z.string(),
|
||||
directory: z.string(),
|
||||
path: z.string(),
|
||||
global: z.boolean(),
|
||||
supportingFiles: z.array(z.string()).optional()
|
||||
supportingFiles: z.array(z.string()).optional(),
|
||||
properties: z.record(z.unknown()).optional()
|
||||
});
|
||||
|
||||
export const zCreateSourceResponse = z.object({
|
||||
@@ -808,7 +815,8 @@ export const zListSourcesRequest = z.object({
|
||||
projectDir: z.union([
|
||||
z.string(),
|
||||
z.null()
|
||||
]).optional()
|
||||
]).optional(),
|
||||
includeProjectSources: z.boolean().optional().default(false)
|
||||
});
|
||||
|
||||
export const zListSourcesResponse = z.object({
|
||||
@@ -823,7 +831,11 @@ export const zUpdateSourceRequest = z.object({
|
||||
path: z.string(),
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
content: z.string()
|
||||
content: z.string(),
|
||||
properties: z.union([
|
||||
z.record(z.unknown()),
|
||||
z.null()
|
||||
]).optional()
|
||||
});
|
||||
|
||||
export const zUpdateSourceResponse = z.object({
|
||||
|
||||
Reference in New Issue
Block a user