|
|
|
@@ -48,7 +48,7 @@ func NewCreateProjectFromTemplate(c *gitea.Client, a *allowlist.Allowlist, tmplO
|
|
|
|
|
func (t *CreateProjectFromTemplate) Descriptor() registry.ToolDescriptor {
|
|
|
|
|
return registry.ToolDescriptor{
|
|
|
|
|
Name: "create_project_from_template",
|
|
|
|
|
Description: "Create a new project repo from a template. Best-effort substitution of placeholders (__PROJECT_NAME__, __MODULE_PATH__) in every file's content AND path (e.g. renaming cmd/__PROJECT_NAME__/): it completes only if the generated branch is promptly writable. If gitea's async generate is slow (infra#179) the repo is still created and partial_failure explains how to finalize locally (`hyperguild new-project`). Check files_substituted and partial_failure. Defaults to the server-configured template; pass template_name to override (e.g. template-go-agent). Pass dispatch_allow=true to also inject a .dispatch-allow file so the project is immediately dispatch-eligible (dispatch#3).",
|
|
|
|
|
Description: "Create a new project repo from a template. Best-effort substitution of placeholders (__PROJECT_NAME__, __MODULE_PATH__) in every file's content AND path (e.g. renaming cmd/__PROJECT_NAME__/): it completes only if the generated branch is promptly writable. If gitea's async generate is slow (infra#179) the repo is still created and partial_failure explains how to finish substituting the placeholders manually. Check files_substituted and partial_failure. Defaults to the server-configured template; pass template_name to override (e.g. template-go-agent). Pass dispatch_allow=true to also inject a .dispatch-allow file so the project is immediately dispatch-eligible (dispatch#3).",
|
|
|
|
|
InputSchema: json.RawMessage(`{
|
|
|
|
|
"type":"object",
|
|
|
|
|
"properties":{
|
|
|
|
@@ -209,11 +209,7 @@ func (t *CreateProjectFromTemplate) Call(ctx context.Context, raw json.RawMessag
|
|
|
|
|
// is best-effort).
|
|
|
|
|
if strings.Contains(result.PartialFailure, "branch does not exist") ||
|
|
|
|
|
strings.Contains(result.PartialFailure, "not found") {
|
|
|
|
|
result.PartialFailure = fmt.Sprintf(
|
|
|
|
|
"repo created, but its branch (%s) was not writable within %ds — gitea's "+
|
|
|
|
|
"template-generate is slow-async on this instance (infra#179), so substitution "+
|
|
|
|
|
"is incomplete (%d file(s) done). Finalize locally with `hyperguild new-project` "+
|
|
|
|
|
"(clone + substitute, no API race). Underlying: %s",
|
|
|
|
|
result.PartialFailure = infra179FinalizeMessage(
|
|
|
|
|
branch, substitutionBudget, len(result.FilesSubstituted), result.PartialFailure)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -227,6 +223,21 @@ func (t *CreateProjectFromTemplate) Call(ctx context.Context, raw json.RawMessag
|
|
|
|
|
return textOK(result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// infra179FinalizeMessage explains the best-effort outcome when gitea's slow
|
|
|
|
|
// async template-generate (infra#179) leaves the branch unwritable within the
|
|
|
|
|
// budget. It names the concrete remaining work — substituting the two
|
|
|
|
|
// placeholders — rather than pointing at a specific tool, so the guidance stays
|
|
|
|
|
// correct regardless of scaffolding-CLI state (gitea-mcp#46).
|
|
|
|
|
func infra179FinalizeMessage(branch string, budget, done int, underlying string) string {
|
|
|
|
|
return fmt.Sprintf(
|
|
|
|
|
"repo created, but its branch (%s) was not writable within %ds — gitea's "+
|
|
|
|
|
"template-generate is slow-async on this instance (infra#179), so substitution "+
|
|
|
|
|
"is incomplete (%d file(s) done). Finish it by cloning the repo and replacing the "+
|
|
|
|
|
"remaining __PROJECT_NAME__ / __MODULE_PATH__ placeholders (in file contents and "+
|
|
|
|
|
"paths), then pushing; or retry create once the branch settles. Underlying: %s",
|
|
|
|
|
branch, budget, done, underlying)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// substitutionBudget bounds how long we retry the first write while the freshly
|
|
|
|
|
// generated branch becomes writable. gitea's /generate returns (and serves reads)
|
|
|
|
|
// before the branch ref is committed, so writes 404 "branch does not exist" for a
|
|
|
|
|