@bradygaster/squad-sdk 0.8.25 → 0.9.0
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/adapter/client.d.ts +17 -0
- package/dist/adapter/client.d.ts.map +1 -1
- package/dist/adapter/client.js +101 -1
- package/dist/adapter/client.js.map +1 -1
- package/dist/agents/history-shadow.d.ts.map +1 -1
- package/dist/agents/history-shadow.js +99 -32
- package/dist/agents/history-shadow.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/model-selector.d.ts +2 -0
- package/dist/agents/model-selector.d.ts.map +1 -1
- package/dist/agents/model-selector.js +41 -35
- package/dist/agents/model-selector.js.map +1 -1
- package/dist/agents/personal.d.ts +35 -0
- package/dist/agents/personal.d.ts.map +1 -0
- package/dist/agents/personal.js +67 -0
- package/dist/agents/personal.js.map +1 -0
- package/dist/builders/index.d.ts +3 -2
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +28 -0
- package/dist/builders/index.js.map +1 -1
- package/dist/builders/types.d.ts +13 -0
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/config/init.d.ts +8 -0
- package/dist/config/init.d.ts.map +1 -1
- package/dist/config/init.js +131 -20
- package/dist/config/init.js.map +1 -1
- package/dist/config/models.d.ts +112 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +329 -18
- package/dist/config/models.js.map +1 -1
- package/dist/coordinator/index.js +2 -2
- package/dist/coordinator/index.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/platform/azure-devops.d.ts +42 -0
- package/dist/platform/azure-devops.d.ts.map +1 -1
- package/dist/platform/azure-devops.js +75 -0
- package/dist/platform/azure-devops.js.map +1 -1
- package/dist/platform/comms-file-log.d.ts.map +1 -1
- package/dist/platform/comms-file-log.js +2 -1
- package/dist/platform/comms-file-log.js.map +1 -1
- package/dist/platform/index.d.ts +2 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +1 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/ralph/capabilities.d.ts +67 -0
- package/dist/ralph/capabilities.d.ts.map +1 -0
- package/dist/ralph/capabilities.js +111 -0
- package/dist/ralph/capabilities.js.map +1 -0
- package/dist/ralph/index.d.ts +2 -0
- package/dist/ralph/index.d.ts.map +1 -1
- package/dist/ralph/index.js +6 -5
- package/dist/ralph/index.js.map +1 -1
- package/dist/ralph/rate-limiting.d.ts +99 -0
- package/dist/ralph/rate-limiting.d.ts.map +1 -0
- package/dist/ralph/rate-limiting.js +170 -0
- package/dist/ralph/rate-limiting.js.map +1 -0
- package/dist/resolution.d.ts +24 -2
- package/dist/resolution.d.ts.map +1 -1
- package/dist/resolution.js +106 -6
- package/dist/resolution.js.map +1 -1
- package/dist/roles/catalog-categories.d.ts +146 -0
- package/dist/roles/catalog-categories.d.ts.map +1 -0
- package/dist/roles/catalog-categories.js +374 -0
- package/dist/roles/catalog-categories.js.map +1 -0
- package/dist/roles/catalog-engineering.d.ts +212 -0
- package/dist/roles/catalog-engineering.d.ts.map +1 -0
- package/dist/roles/catalog-engineering.js +549 -0
- package/dist/roles/catalog-engineering.js.map +1 -0
- package/dist/roles/catalog.d.ts +24 -0
- package/dist/roles/catalog.d.ts.map +1 -0
- package/dist/roles/catalog.js +28 -0
- package/dist/roles/catalog.js.map +1 -0
- package/dist/roles/index.d.ts +69 -0
- package/dist/roles/index.d.ts.map +1 -0
- package/dist/roles/index.js +197 -0
- package/dist/roles/index.js.map +1 -0
- package/dist/roles/types.d.ts +87 -0
- package/dist/roles/types.d.ts.map +1 -0
- package/dist/roles/types.js +14 -0
- package/dist/roles/types.js.map +1 -0
- package/dist/runtime/benchmarks.js +5 -5
- package/dist/runtime/benchmarks.js.map +1 -1
- package/dist/runtime/constants.d.ts +2 -2
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +5 -3
- package/dist/runtime/constants.js.map +1 -1
- package/dist/runtime/cross-squad.d.ts +118 -0
- package/dist/runtime/cross-squad.d.ts.map +1 -0
- package/dist/runtime/cross-squad.js +234 -0
- package/dist/runtime/cross-squad.js.map +1 -0
- package/dist/runtime/otel-init.d.ts +24 -17
- package/dist/runtime/otel-init.d.ts.map +1 -1
- package/dist/runtime/otel-init.js +29 -20
- package/dist/runtime/otel-init.js.map +1 -1
- package/dist/runtime/otel-metrics.d.ts +5 -0
- package/dist/runtime/otel-metrics.d.ts.map +1 -1
- package/dist/runtime/otel-metrics.js +54 -0
- package/dist/runtime/otel-metrics.js.map +1 -1
- package/dist/runtime/rework.d.ts +71 -0
- package/dist/runtime/rework.d.ts.map +1 -0
- package/dist/runtime/rework.js +107 -0
- package/dist/runtime/rework.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +128 -0
- package/dist/runtime/scheduler.d.ts.map +1 -0
- package/dist/runtime/scheduler.js +427 -0
- package/dist/runtime/scheduler.js.map +1 -0
- package/dist/runtime/squad-observer.d.ts.map +1 -1
- package/dist/runtime/squad-observer.js +4 -0
- package/dist/runtime/squad-observer.js.map +1 -1
- package/dist/runtime/streaming.d.ts +2 -0
- package/dist/runtime/streaming.d.ts.map +1 -1
- package/dist/runtime/streaming.js +6 -0
- package/dist/runtime/streaming.js.map +1 -1
- package/dist/runtime/telemetry.d.ts +2 -0
- package/dist/runtime/telemetry.d.ts.map +1 -1
- package/dist/runtime/telemetry.js +6 -0
- package/dist/runtime/telemetry.js.map +1 -1
- package/dist/sharing/consult.d.ts +2 -2
- package/dist/sharing/consult.js +6 -6
- package/dist/sharing/consult.js.map +1 -1
- package/dist/sharing/export.d.ts.map +1 -1
- package/dist/sharing/export.js +17 -4
- package/dist/sharing/export.js.map +1 -1
- package/dist/skills/handler-types.d.ts +271 -0
- package/dist/skills/handler-types.d.ts.map +1 -0
- package/dist/skills/handler-types.js +31 -0
- package/dist/skills/handler-types.js.map +1 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-script-loader.d.ts +65 -0
- package/dist/skills/skill-script-loader.d.ts.map +1 -0
- package/dist/skills/skill-script-loader.js +227 -0
- package/dist/skills/skill-script-loader.js.map +1 -0
- package/dist/skills/skill-source.d.ts.map +1 -1
- package/dist/skills/skill-source.js +5 -1
- package/dist/skills/skill-source.js.map +1 -1
- package/dist/tools/index.d.ts +10 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +49 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/upstream/resolver.d.ts.map +1 -1
- package/dist/upstream/resolver.js +14 -5
- package/dist/upstream/resolver.js.map +1 -1
- package/package.json +34 -3
- package/templates/casting/Futurama.json +10 -0
- package/templates/casting-policy.json +4 -2
- package/templates/casting-reference.md +104 -0
- package/templates/cooperative-rate-limiting.md +229 -0
- package/templates/issue-lifecycle.md +412 -0
- package/templates/keda-scaler.md +164 -0
- package/templates/machine-capabilities.md +75 -0
- package/templates/mcp-config.md +0 -8
- package/templates/orchestration-log.md +27 -27
- package/templates/package.json +3 -0
- package/templates/ralph-circuit-breaker.md +313 -0
- package/templates/ralph-triage.js +543 -0
- package/templates/routing.md +5 -20
- package/templates/schedule.json +19 -0
- package/templates/scribe-charter.md +1 -1
- package/templates/skills/agent-collaboration/SKILL.md +42 -0
- package/templates/skills/agent-conduct/SKILL.md +24 -0
- package/templates/skills/architectural-proposals/SKILL.md +151 -0
- package/templates/skills/ci-validation-gates/SKILL.md +84 -0
- package/templates/skills/cli-wiring/SKILL.md +47 -0
- package/templates/skills/client-compatibility/SKILL.md +89 -0
- package/templates/skills/cross-squad/SKILL.md +114 -0
- package/templates/skills/distributed-mesh/SKILL.md +287 -0
- package/templates/skills/distributed-mesh/mesh.json.example +30 -0
- package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
- package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
- package/templates/skills/docs-standards/SKILL.md +71 -0
- package/templates/skills/economy-mode/SKILL.md +114 -0
- package/templates/skills/external-comms/SKILL.md +329 -0
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
- package/templates/skills/git-workflow/SKILL.md +204 -0
- package/templates/skills/github-multi-account/SKILL.md +95 -0
- package/templates/skills/history-hygiene/SKILL.md +36 -0
- package/templates/skills/humanizer/SKILL.md +105 -0
- package/templates/skills/init-mode/SKILL.md +102 -0
- package/templates/skills/model-selection/SKILL.md +117 -0
- package/templates/skills/nap/SKILL.md +24 -0
- package/templates/skills/personal-squad/SKILL.md +57 -0
- package/templates/skills/release-process/SKILL.md +423 -0
- package/templates/skills/reskill/SKILL.md +92 -0
- package/templates/skills/reviewer-protocol/SKILL.md +79 -0
- package/templates/skills/secret-handling/SKILL.md +200 -0
- package/templates/skills/session-recovery/SKILL.md +155 -0
- package/templates/skills/squad-conventions/SKILL.md +69 -0
- package/templates/skills/test-discipline/SKILL.md +37 -0
- package/templates/skills/windows-compatibility/SKILL.md +74 -0
- package/templates/squad.agent.md +1287 -1146
- package/templates/workflows/squad-docs.yml +8 -4
- package/templates/workflows/squad-heartbeat.yml +55 -200
- package/templates/workflows/squad-insider-release.yml +1 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type system for the skill-script model.
|
|
3
|
+
*
|
|
4
|
+
* This module defines the complete type contract for backend skills in `.copilot/skills/`.
|
|
5
|
+
* Skills contain `scripts/` directories with executable JS handlers that replace built-in
|
|
6
|
+
* tool handlers in ToolRegistry.
|
|
7
|
+
*
|
|
8
|
+
* The skill-script model enables stateful, framework-aware backends for tasks, decisions,
|
|
9
|
+
* memories, and logging concerns. Handlers are ordinary async functions that return
|
|
10
|
+
* SquadToolResult values.
|
|
11
|
+
*/
|
|
12
|
+
import type { SquadToolResult, SquadTool } from "../adapter/types.js";
|
|
13
|
+
/**
|
|
14
|
+
* Arguments for squad_create_issue.
|
|
15
|
+
* All tool arg interfaces include [key: string]: unknown for skill-documented extensions.
|
|
16
|
+
*/
|
|
17
|
+
export interface CreateIssueArgs {
|
|
18
|
+
title: string;
|
|
19
|
+
body?: string;
|
|
20
|
+
assignee?: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Arguments for squad_update_issue.
|
|
25
|
+
*/
|
|
26
|
+
export interface UpdateIssueArgs {
|
|
27
|
+
issueId: string | number;
|
|
28
|
+
title?: string;
|
|
29
|
+
body?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Arguments for squad_list_issues.
|
|
34
|
+
*/
|
|
35
|
+
export interface ListIssuesArgs {
|
|
36
|
+
status?: "all" | "open" | "closed";
|
|
37
|
+
limit?: number;
|
|
38
|
+
[key: string]: unknown;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Arguments for squad_close_issue.
|
|
42
|
+
*/
|
|
43
|
+
export interface CloseIssueArgs {
|
|
44
|
+
issueId: string | number;
|
|
45
|
+
comment?: string;
|
|
46
|
+
[key: string]: unknown;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Arguments for squad_create_decision.
|
|
50
|
+
*/
|
|
51
|
+
export interface CreateDecisionArgs {
|
|
52
|
+
author: string;
|
|
53
|
+
summary: string;
|
|
54
|
+
body: string;
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Arguments for squad_list_decisions.
|
|
59
|
+
*/
|
|
60
|
+
export interface ListDecisionsArgs {
|
|
61
|
+
status?: "all" | "pending" | "merged";
|
|
62
|
+
limit?: number;
|
|
63
|
+
[key: string]: unknown;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Arguments for squad_merge_decision.
|
|
67
|
+
*/
|
|
68
|
+
export interface MergeDecisionArgs {
|
|
69
|
+
slugs?: string[];
|
|
70
|
+
[key: string]: unknown;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Arguments for squad_create_memory.
|
|
74
|
+
*/
|
|
75
|
+
export interface CreateMemoryArgs {
|
|
76
|
+
content: string;
|
|
77
|
+
agent?: string;
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Arguments for squad_list_memories.
|
|
82
|
+
*/
|
|
83
|
+
export interface ListMemoriesArgs {
|
|
84
|
+
agent?: string;
|
|
85
|
+
limit?: number;
|
|
86
|
+
[key: string]: unknown;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Arguments for squad_create_log.
|
|
90
|
+
*/
|
|
91
|
+
export interface CreateLogArgs {
|
|
92
|
+
kind: "orchestration" | "session";
|
|
93
|
+
content: string;
|
|
94
|
+
agent?: string;
|
|
95
|
+
[key: string]: unknown;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Arguments for squad_list_logs.
|
|
99
|
+
*/
|
|
100
|
+
export interface ListLogsArgs {
|
|
101
|
+
kind?: "orchestration" | "session";
|
|
102
|
+
limit?: number;
|
|
103
|
+
[key: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Skill handler function.
|
|
107
|
+
*
|
|
108
|
+
* @param args - Tool input matching the tool's schema
|
|
109
|
+
* @param config - Non-framework keys from the tracking config entry (excludes 'skill', 'disposeTimeoutMs')
|
|
110
|
+
* @returns SquadToolResult (string or SquadToolResultObject)
|
|
111
|
+
*/
|
|
112
|
+
export type SkillHandler<TArgs = unknown> = (args: TArgs, config: Record<string, unknown>) => Promise<SquadToolResult> | SquadToolResult;
|
|
113
|
+
/**
|
|
114
|
+
* Lifecycle hooks for stateful backend skills.
|
|
115
|
+
* lifecycle.js in the scripts/ dir exports these.
|
|
116
|
+
*/
|
|
117
|
+
export interface HandlerLifecycle {
|
|
118
|
+
/**
|
|
119
|
+
* Called once after handler resolution, before first tool call.
|
|
120
|
+
* init() must be idempotent.
|
|
121
|
+
*/
|
|
122
|
+
init?(config: Record<string, unknown>): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Called once at session end.
|
|
125
|
+
* Must be safe to call even if init() partially failed.
|
|
126
|
+
*/
|
|
127
|
+
dispose?(): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Task concern handlers (squad_*_issue).
|
|
131
|
+
*/
|
|
132
|
+
export interface TaskHandlers extends HandlerLifecycle {
|
|
133
|
+
squad_create_issue?: SkillHandler<CreateIssueArgs>;
|
|
134
|
+
squad_update_issue?: SkillHandler<UpdateIssueArgs>;
|
|
135
|
+
squad_list_issues?: SkillHandler<ListIssuesArgs>;
|
|
136
|
+
squad_close_issue?: SkillHandler<CloseIssueArgs>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Decision concern handlers (squad_*_decision).
|
|
140
|
+
*/
|
|
141
|
+
export interface DecisionHandlers extends HandlerLifecycle {
|
|
142
|
+
squad_create_decision?: SkillHandler<CreateDecisionArgs>;
|
|
143
|
+
squad_list_decisions?: SkillHandler<ListDecisionsArgs>;
|
|
144
|
+
squad_merge_decision?: SkillHandler<MergeDecisionArgs>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Memory concern handlers (squad_*_memory).
|
|
148
|
+
*/
|
|
149
|
+
export interface MemoryHandlers extends HandlerLifecycle {
|
|
150
|
+
squad_create_memory?: SkillHandler<CreateMemoryArgs>;
|
|
151
|
+
squad_list_memories?: SkillHandler<ListMemoriesArgs>;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Logging concern handlers (squad_*_log).
|
|
155
|
+
*/
|
|
156
|
+
export interface LogHandlers extends HandlerLifecycle {
|
|
157
|
+
squad_create_log?: SkillHandler<CreateLogArgs>;
|
|
158
|
+
squad_list_logs?: SkillHandler<ListLogsArgs>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Union of all handler interfaces.
|
|
162
|
+
*/
|
|
163
|
+
export type AllHandlers = TaskHandlers & DecisionHandlers & MemoryHandlers & LogHandlers;
|
|
164
|
+
/**
|
|
165
|
+
* Strip HandlerLifecycle keys, keep only tool-name keys.
|
|
166
|
+
*/
|
|
167
|
+
type OwnKeys<T> = Exclude<keyof T, keyof HandlerLifecycle>;
|
|
168
|
+
/**
|
|
169
|
+
* true if A and B share no tool-name keys; never otherwise.
|
|
170
|
+
*/
|
|
171
|
+
type AssertDisjoint<A, B> = Extract<OwnKeys<A>, OwnKeys<B>> extends never ? true : never;
|
|
172
|
+
export type _TaskDecision = AssertDisjoint<TaskHandlers, DecisionHandlers>;
|
|
173
|
+
export type _TaskMemory = AssertDisjoint<TaskHandlers, MemoryHandlers>;
|
|
174
|
+
export type _TaskLog = AssertDisjoint<TaskHandlers, LogHandlers>;
|
|
175
|
+
export type _DecisionMemory = AssertDisjoint<DecisionHandlers, MemoryHandlers>;
|
|
176
|
+
export type _DecisionLog = AssertDisjoint<DecisionHandlers, LogHandlers>;
|
|
177
|
+
export type _MemoryLog = AssertDisjoint<MemoryHandlers, LogHandlers>;
|
|
178
|
+
/**
|
|
179
|
+
* Maps concern names to their handler interfaces.
|
|
180
|
+
*/
|
|
181
|
+
export interface ConcernMap {
|
|
182
|
+
tasks: TaskHandlers;
|
|
183
|
+
decisions: DecisionHandlers;
|
|
184
|
+
memories: MemoryHandlers;
|
|
185
|
+
logging: LogHandlers;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Valid concern names.
|
|
189
|
+
*/
|
|
190
|
+
export type Concern = keyof ConcernMap;
|
|
191
|
+
/**
|
|
192
|
+
* Return type for SkillScriptLoader.load().
|
|
193
|
+
*/
|
|
194
|
+
export interface LoadResult {
|
|
195
|
+
/**
|
|
196
|
+
* Fully-formed SquadTool entries — skill handlers combined with built-in schemas.
|
|
197
|
+
*/
|
|
198
|
+
tools: SquadTool[];
|
|
199
|
+
/**
|
|
200
|
+
* Lifecycle hooks from scripts/lifecycle.js, if present.
|
|
201
|
+
*/
|
|
202
|
+
lifecycle?: {
|
|
203
|
+
init?(config: Record<string, unknown>): Promise<void>;
|
|
204
|
+
dispose?(): Promise<void>;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Skill configuration entry.
|
|
209
|
+
*
|
|
210
|
+
* Specifies a skill directory path and optional disposal timeout.
|
|
211
|
+
* The 'package' key is reserved for future use and forbidden here.
|
|
212
|
+
*
|
|
213
|
+
* @warning **Security note:** `backendConfig` is for non-secret runtime configuration (URLs, feature
|
|
214
|
+
* flags, timeouts). Do NOT put credentials, tokens, or secrets in `backendConfig` — this config is
|
|
215
|
+
* part of the skill definition and will be committed to the repository. Handler scripts run with full
|
|
216
|
+
* process trust and can access the filesystem and the network. Only load skills from trusted sources.
|
|
217
|
+
*/
|
|
218
|
+
export interface SkillConfig {
|
|
219
|
+
/** Path to skill directory (relative to squad root) */
|
|
220
|
+
skill: string;
|
|
221
|
+
/** Prevent future package key coexisting with skill */
|
|
222
|
+
package?: never;
|
|
223
|
+
/** Timeout for dispose() in ms (default: 10000) */
|
|
224
|
+
disposeTimeoutMs?: number;
|
|
225
|
+
[key: string]: unknown;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* A reference to a backend:
|
|
229
|
+
* - undefined → built-in markdown (default)
|
|
230
|
+
* - "markdown" → built-in markdown (explicit reset)
|
|
231
|
+
* - "noop" → silent no-op (disables the concern)
|
|
232
|
+
* - { skill, ...opts } → skill directory with config options
|
|
233
|
+
*/
|
|
234
|
+
export type BackendRef = "markdown" | "noop" | SkillConfig;
|
|
235
|
+
/**
|
|
236
|
+
* Direct handler registration (alternative to skill path).
|
|
237
|
+
* Used for programmatically-provided handlers.
|
|
238
|
+
*/
|
|
239
|
+
export interface HandlerRegistration<H extends HandlerLifecycle> {
|
|
240
|
+
handlers: H;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Tracking configuration for backend skills.
|
|
244
|
+
*
|
|
245
|
+
* Controls which backend (markdown, noop, or skill) serves each concern.
|
|
246
|
+
* Supports a global default with per-concern overrides.
|
|
247
|
+
*/
|
|
248
|
+
export interface TrackingConfig {
|
|
249
|
+
/** Backend for ALL concerns unless individually overridden */
|
|
250
|
+
default?: BackendRef;
|
|
251
|
+
decisions?: BackendRef | HandlerRegistration<DecisionHandlers>;
|
|
252
|
+
memories?: BackendRef | HandlerRegistration<MemoryHandlers>;
|
|
253
|
+
tasks?: BackendRef | HandlerRegistration<TaskHandlers>;
|
|
254
|
+
logging?: BackendRef | HandlerRegistration<LogHandlers>;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Identity function for type inference in handler scripts.
|
|
258
|
+
*
|
|
259
|
+
* Provides compile-time safety when authoring TypeScript handlers.
|
|
260
|
+
* The compiled .js output is a plain function — no runtime dependency on this.
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* export default defineHandler<CreateIssueArgs>(async (args, config) => {
|
|
265
|
+
* return { type: "success", text: `Issue created: ${args.title}` };
|
|
266
|
+
* });
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
export declare function defineHandler<TArgs = unknown>(handler: SkillHandler<TArgs>): SkillHandler<TArgs>;
|
|
270
|
+
export {};
|
|
271
|
+
//# sourceMappingURL=handler-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-types.d.ts","sourceRoot":"","sources":["../../src/skills/handler-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type system for the skill-script model.
|
|
3
|
+
*
|
|
4
|
+
* This module defines the complete type contract for backend skills in `.copilot/skills/`.
|
|
5
|
+
* Skills contain `scripts/` directories with executable JS handlers that replace built-in
|
|
6
|
+
* tool handlers in ToolRegistry.
|
|
7
|
+
*
|
|
8
|
+
* The skill-script model enables stateful, framework-aware backends for tasks, decisions,
|
|
9
|
+
* memories, and logging concerns. Handlers are ordinary async functions that return
|
|
10
|
+
* SquadToolResult values.
|
|
11
|
+
*/
|
|
12
|
+
// Compile fails if any pair shares a tool name:
|
|
13
|
+
const _disjointProof = [true, true, true, true, true, true];
|
|
14
|
+
// ─── defineHandler Helper ────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Identity function for type inference in handler scripts.
|
|
17
|
+
*
|
|
18
|
+
* Provides compile-time safety when authoring TypeScript handlers.
|
|
19
|
+
* The compiled .js output is a plain function — no runtime dependency on this.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* export default defineHandler<CreateIssueArgs>(async (args, config) => {
|
|
24
|
+
* return { type: "success", text: `Issue created: ${args.title}` };
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function defineHandler(handler) {
|
|
29
|
+
return handler;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=handler-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-types.js","sourceRoot":"","sources":["../../src/skills/handler-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgNH,gDAAgD;AAChD,MAAM,cAAc,GAOhB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AA8FzC,gFAAgF;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA4B;IAE5B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/skills/index.d.ts
CHANGED
|
@@ -46,4 +46,7 @@ export declare class SkillRegistry {
|
|
|
46
46
|
*/
|
|
47
47
|
loadSkill(skillId: string): string | undefined;
|
|
48
48
|
}
|
|
49
|
+
export * from './handler-types.js';
|
|
50
|
+
export { SkillScriptLoader, resolveSkillPath } from './skill-script-loader.js';
|
|
51
|
+
export type { LoadResult } from './handler-types.js';
|
|
49
52
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,cAAc,mBAAmB,CAAC;AAIlC,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA2C;IAEzD,mCAAmC;IACnC,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAI3C,gCAAgC;IAChC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIzC,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAItD,iCAAiC;IACjC,YAAY,IAAI,eAAe,EAAE;IAIjC,mCAAmC;IACnC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;OASG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE;IA0C1D;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG/C"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,cAAc,mBAAmB,CAAC;AAIlC,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA2C;IAEzD,mCAAmC;IACnC,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAI3C,gCAAgC;IAChC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIzC,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAItD,iCAAiC;IACjC,YAAY,IAAI,eAAe,EAAE;IAIjC,mCAAmC;IACnC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;OASG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE;IA0C1D;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG/C;AAID,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/skills/index.js
CHANGED
|
@@ -82,4 +82,7 @@ export class SkillRegistry {
|
|
|
82
82
|
return this.skills.get(skillId)?.content;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
// --- Skill Script System Exports ---
|
|
86
|
+
export * from './handler-types.js';
|
|
87
|
+
export { SkillScriptLoader, resolveSkillPath } from './skill-script-loader.js';
|
|
85
88
|
//# sourceMappingURL=index.js.map
|
package/dist/skills/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Script Loader
|
|
3
|
+
*
|
|
4
|
+
* Runtime loader for executable skill handlers from backend skill directories.
|
|
5
|
+
* Backend skills in `.copilot/skills/{name}/scripts/` contain `.js` handler files
|
|
6
|
+
* that replace built-in tool handlers in ToolRegistry.
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* - Loading concern-specific handler scripts (tasks, decisions, memories, logging)
|
|
10
|
+
* - Dynamic import() of handler scripts with lifecycle hooks
|
|
11
|
+
* - Path containment validation for security
|
|
12
|
+
* - Partial implementations (missing handlers are silently skipped)
|
|
13
|
+
*/
|
|
14
|
+
import type { LoadResult } from './handler-types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a skill path relative to project/team roots with containment validation.
|
|
17
|
+
*
|
|
18
|
+
* Algorithm:
|
|
19
|
+
* 1. Absolute paths used as-is
|
|
20
|
+
* 2. With teamRoot: resolve `.copilot/` paths from projectRoot and strip legacy `.squad/` paths relative to teamRoot
|
|
21
|
+
* 3. Without teamRoot: resolve relative to projectRoot
|
|
22
|
+
* 4. Path containment check: final path must be within projectRoot or teamRoot
|
|
23
|
+
* 5. Reject paths with `..` segments that escape the boundary (throw Error)
|
|
24
|
+
*
|
|
25
|
+
* @param skillPath - Path from skill configuration (absolute or relative)
|
|
26
|
+
* @param projectRoot - Project root directory (absolute)
|
|
27
|
+
* @param teamRoot - Team root directory (absolute, optional)
|
|
28
|
+
* @returns Resolved absolute path
|
|
29
|
+
* @throws Error if path escapes containment boundaries
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveSkillPath(skillPath: string, projectRoot: string, teamRoot?: string): string;
|
|
32
|
+
export declare class SkillScriptLoader {
|
|
33
|
+
private getToolSchema;
|
|
34
|
+
constructor(getToolSchema: (toolName: string) => {
|
|
35
|
+
description: string;
|
|
36
|
+
parameters: Record<string, unknown>;
|
|
37
|
+
} | undefined);
|
|
38
|
+
/**
|
|
39
|
+
* Load handler scripts from a backend skill directory by scanning `scripts/` for `.js` files.
|
|
40
|
+
*
|
|
41
|
+
* Algorithm:
|
|
42
|
+
* 1. Check for `scripts/` directory — return null if missing (triggers markdown fallback)
|
|
43
|
+
* 2. Scan scripts/ for all .js files (excluding lifecycle.js)
|
|
44
|
+
* 3. For each file, derive tool name: prepend 'squad_' to the filename stem
|
|
45
|
+
* a. import() the script using toFileUrl (with Windows path normalization)
|
|
46
|
+
* b. Validate: module.default must be a function — if not, THROW (not silent skip)
|
|
47
|
+
* c. Get the tool's schema via this.getToolSchema(toolName)
|
|
48
|
+
* d. If schema not found → skip with warning (tool not registered in ToolRegistry)
|
|
49
|
+
* e. Produce a SquadTool entry with wrapSkillHandler()
|
|
50
|
+
* 4. Load scripts/lifecycle.js if present (import() it)
|
|
51
|
+
* Extract init and dispose named exports if they are functions
|
|
52
|
+
* 5. Return { tools, lifecycle } or { tools } if no lifecycle
|
|
53
|
+
*
|
|
54
|
+
* @param skillPath - Resolved absolute path to the skill directory
|
|
55
|
+
* @param backendConfig - Backend configuration to pass to handlers
|
|
56
|
+
* @returns LoadResult with tools and optional lifecycle, or null if no scripts/ directory
|
|
57
|
+
*
|
|
58
|
+
* @warning **Security note:** `backendConfig` is for non-secret runtime configuration (URLs, feature
|
|
59
|
+
* flags, timeouts). Do NOT put credentials, tokens, or secrets in `backendConfig` — this config is
|
|
60
|
+
* part of the skill definition and will be committed to the repository. Handler scripts run with full
|
|
61
|
+
* process trust and can access the filesystem and the network. Only load skills from trusted sources.
|
|
62
|
+
*/
|
|
63
|
+
load(skillPath: string, backendConfig: Record<string, unknown>): Promise<LoadResult | null>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=skill-script-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-script-loader.d.ts","sourceRoot":"","sources":["../../src/skills/skill-script-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EACV,UAAU,EAGX,MAAM,oBAAoB,CAAC;AA6D5B;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CA0CR;AAID,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,SAAS;IAGvH;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,IAAI,CACR,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CA4E9B"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Script Loader
|
|
3
|
+
*
|
|
4
|
+
* Runtime loader for executable skill handlers from backend skill directories.
|
|
5
|
+
* Backend skills in `.copilot/skills/{name}/scripts/` contain `.js` handler files
|
|
6
|
+
* that replace built-in tool handlers in ToolRegistry.
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* - Loading concern-specific handler scripts (tasks, decisions, memories, logging)
|
|
10
|
+
* - Dynamic import() of handler scripts with lifecycle hooks
|
|
11
|
+
* - Path containment validation for security
|
|
12
|
+
* - Partial implementations (missing handlers are silently skipped)
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readdirSync, realpathSync } from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import { pathToFileURL } from 'node:url';
|
|
17
|
+
import { trace, SpanStatusCode } from '../runtime/otel-api.js';
|
|
18
|
+
const tracer = trace.getTracer('squad-sdk');
|
|
19
|
+
// --- OTel Handler Wrapping ---
|
|
20
|
+
/**
|
|
21
|
+
* Wrap a skill handler with OTel span instrumentation.
|
|
22
|
+
* Mirrors the wrapping applied to built-in tools by defineTool() so skill-dispatched
|
|
23
|
+
* calls appear in traces, distinguished by 'tool.skill_dispatched: true'.
|
|
24
|
+
*
|
|
25
|
+
* This is intentionally a local copy — skill handlers and tool handlers have different
|
|
26
|
+
* signatures and concerns; they should not share implementation.
|
|
27
|
+
*/
|
|
28
|
+
function wrapSkillHandlerWithSpan(name, skillHandler, backendConfig) {
|
|
29
|
+
return async (args, _invocation) => {
|
|
30
|
+
const span = tracer.startSpan('squad.skill.call', {
|
|
31
|
+
attributes: { 'tool.name': name, 'tool.skill_dispatched': true },
|
|
32
|
+
});
|
|
33
|
+
const startTime = Date.now();
|
|
34
|
+
try {
|
|
35
|
+
const result = await skillHandler(args, backendConfig);
|
|
36
|
+
const durationMs = Date.now() - startTime;
|
|
37
|
+
span.addEvent('squad.skill.result', typeof result === 'string'
|
|
38
|
+
? { 'result.type': 'unknown', 'result.length': result.length, 'duration_ms': durationMs, 'success': true }
|
|
39
|
+
: { 'result.type': result.resultType ?? 'unknown', 'result.length': (result.textResultForLlm ?? '').length, 'duration_ms': durationMs, 'success': result.resultType !== 'failure' });
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const durationMs = Date.now() - startTime;
|
|
44
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: err instanceof Error ? err.message : String(err) });
|
|
45
|
+
span.addEvent('squad.skill.error', {
|
|
46
|
+
'error.type': err instanceof Error ? err.constructor.name : 'unknown',
|
|
47
|
+
'error.message': err instanceof Error ? err.message : String(err),
|
|
48
|
+
'duration_ms': durationMs,
|
|
49
|
+
});
|
|
50
|
+
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
span.end();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// --- Helpers ---
|
|
59
|
+
/**
|
|
60
|
+
* Normalize path separators for consistent module cache keys on Windows.
|
|
61
|
+
* pathToFileURL() can create different URLs from different path separator styles,
|
|
62
|
+
* leading to duplicate module instances. Always normalize before conversion.
|
|
63
|
+
*/
|
|
64
|
+
function toFileUrl(filePath) {
|
|
65
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
66
|
+
return pathToFileURL(normalized).href;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolve a skill path relative to project/team roots with containment validation.
|
|
70
|
+
*
|
|
71
|
+
* Algorithm:
|
|
72
|
+
* 1. Absolute paths used as-is
|
|
73
|
+
* 2. With teamRoot: resolve `.copilot/` paths from projectRoot and strip legacy `.squad/` paths relative to teamRoot
|
|
74
|
+
* 3. Without teamRoot: resolve relative to projectRoot
|
|
75
|
+
* 4. Path containment check: final path must be within projectRoot or teamRoot
|
|
76
|
+
* 5. Reject paths with `..` segments that escape the boundary (throw Error)
|
|
77
|
+
*
|
|
78
|
+
* @param skillPath - Path from skill configuration (absolute or relative)
|
|
79
|
+
* @param projectRoot - Project root directory (absolute)
|
|
80
|
+
* @param teamRoot - Team root directory (absolute, optional)
|
|
81
|
+
* @returns Resolved absolute path
|
|
82
|
+
* @throws Error if path escapes containment boundaries
|
|
83
|
+
*/
|
|
84
|
+
export function resolveSkillPath(skillPath, projectRoot, teamRoot) {
|
|
85
|
+
/** Resolve symlinks; fall back to the logical path if it doesn't exist yet (write case). */
|
|
86
|
+
function realOrLogical(p) {
|
|
87
|
+
try {
|
|
88
|
+
return realpathSync(p);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return p;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** True if `p` is equal to `root` or directly inside it. */
|
|
95
|
+
function isContained(p, root) {
|
|
96
|
+
const r = path.resolve(root);
|
|
97
|
+
return p === r || p.startsWith(r + path.sep);
|
|
98
|
+
}
|
|
99
|
+
// 1. Absolute paths used as-is
|
|
100
|
+
if (path.isAbsolute(skillPath)) {
|
|
101
|
+
const resolved = path.resolve(skillPath);
|
|
102
|
+
const real = realOrLogical(resolved);
|
|
103
|
+
const inside = (teamRoot ? isContained(real, teamRoot) || isContained(real, projectRoot) : isContained(real, projectRoot));
|
|
104
|
+
if (!inside)
|
|
105
|
+
throw new Error(`Path escapes containment: ${skillPath} is outside project and team roots`);
|
|
106
|
+
return resolved;
|
|
107
|
+
}
|
|
108
|
+
// 2. With teamRoot: resolve .copilot/ paths from projectRoot, legacy .squad/ paths from teamRoot
|
|
109
|
+
if (teamRoot) {
|
|
110
|
+
if (skillPath.startsWith('.copilot/')) {
|
|
111
|
+
const resolved = path.resolve(projectRoot, skillPath);
|
|
112
|
+
const real = realOrLogical(resolved);
|
|
113
|
+
if (!isContained(real, projectRoot))
|
|
114
|
+
throw new Error(`Path escapes containment: ${skillPath} resolves outside project root`);
|
|
115
|
+
return resolved;
|
|
116
|
+
}
|
|
117
|
+
const stripped = skillPath.startsWith('.squad/') ? skillPath.slice(7) : skillPath;
|
|
118
|
+
const resolved = path.resolve(teamRoot, stripped);
|
|
119
|
+
const real = realOrLogical(resolved);
|
|
120
|
+
if (!isContained(real, teamRoot))
|
|
121
|
+
throw new Error(`Path escapes containment: ${skillPath} resolves outside team root`);
|
|
122
|
+
return resolved;
|
|
123
|
+
}
|
|
124
|
+
// 3. Without teamRoot: resolve relative to projectRoot
|
|
125
|
+
const resolved = path.resolve(projectRoot, skillPath);
|
|
126
|
+
const real = realOrLogical(resolved);
|
|
127
|
+
if (!isContained(real, projectRoot))
|
|
128
|
+
throw new Error(`Path escapes containment: ${skillPath} resolves outside project root`);
|
|
129
|
+
return resolved;
|
|
130
|
+
}
|
|
131
|
+
// --- SkillScriptLoader ---
|
|
132
|
+
export class SkillScriptLoader {
|
|
133
|
+
getToolSchema;
|
|
134
|
+
constructor(getToolSchema) {
|
|
135
|
+
this.getToolSchema = getToolSchema;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Load handler scripts from a backend skill directory by scanning `scripts/` for `.js` files.
|
|
139
|
+
*
|
|
140
|
+
* Algorithm:
|
|
141
|
+
* 1. Check for `scripts/` directory — return null if missing (triggers markdown fallback)
|
|
142
|
+
* 2. Scan scripts/ for all .js files (excluding lifecycle.js)
|
|
143
|
+
* 3. For each file, derive tool name: prepend 'squad_' to the filename stem
|
|
144
|
+
* a. import() the script using toFileUrl (with Windows path normalization)
|
|
145
|
+
* b. Validate: module.default must be a function — if not, THROW (not silent skip)
|
|
146
|
+
* c. Get the tool's schema via this.getToolSchema(toolName)
|
|
147
|
+
* d. If schema not found → skip with warning (tool not registered in ToolRegistry)
|
|
148
|
+
* e. Produce a SquadTool entry with wrapSkillHandler()
|
|
149
|
+
* 4. Load scripts/lifecycle.js if present (import() it)
|
|
150
|
+
* Extract init and dispose named exports if they are functions
|
|
151
|
+
* 5. Return { tools, lifecycle } or { tools } if no lifecycle
|
|
152
|
+
*
|
|
153
|
+
* @param skillPath - Resolved absolute path to the skill directory
|
|
154
|
+
* @param backendConfig - Backend configuration to pass to handlers
|
|
155
|
+
* @returns LoadResult with tools and optional lifecycle, or null if no scripts/ directory
|
|
156
|
+
*
|
|
157
|
+
* @warning **Security note:** `backendConfig` is for non-secret runtime configuration (URLs, feature
|
|
158
|
+
* flags, timeouts). Do NOT put credentials, tokens, or secrets in `backendConfig` — this config is
|
|
159
|
+
* part of the skill definition and will be committed to the repository. Handler scripts run with full
|
|
160
|
+
* process trust and can access the filesystem and the network. Only load skills from trusted sources.
|
|
161
|
+
*/
|
|
162
|
+
async load(skillPath, backendConfig) {
|
|
163
|
+
// 1. Check for scripts/ directory
|
|
164
|
+
const scriptsDir = path.join(skillPath, 'scripts');
|
|
165
|
+
if (!existsSync(scriptsDir)) {
|
|
166
|
+
return null; // Triggers markdown fallback
|
|
167
|
+
}
|
|
168
|
+
// 2. Scan scripts/ for handler files — everything except lifecycle.js
|
|
169
|
+
const scriptFiles = readdirSync(scriptsDir).filter((f) => f.endsWith('.js') && f !== 'lifecycle.js');
|
|
170
|
+
const tools = [];
|
|
171
|
+
// 3. Load each discovered handler script
|
|
172
|
+
for (const scriptName of scriptFiles) {
|
|
173
|
+
// Derive tool name from filename: create_issue.js → squad_create_issue
|
|
174
|
+
const toolName = 'squad_' + scriptName.slice(0, -3);
|
|
175
|
+
const scriptPath = path.join(scriptsDir, scriptName);
|
|
176
|
+
// c. Get the tool's schema — outside the import try block so schema errors are attributed correctly
|
|
177
|
+
const schema = this.getToolSchema(toolName);
|
|
178
|
+
if (!schema) {
|
|
179
|
+
console.warn(`[SkillScriptLoader] Tool schema not found for ${toolName}, skipping`);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// d. Dynamic import — errors here mean the script itself is broken
|
|
183
|
+
try {
|
|
184
|
+
const scriptUrl = toFileUrl(scriptPath);
|
|
185
|
+
const module = await import(scriptUrl);
|
|
186
|
+
// b. Validate: module.default must be a function
|
|
187
|
+
if (typeof module.default !== 'function') {
|
|
188
|
+
throw new Error(`Handler script ${scriptName} does not export a default function`);
|
|
189
|
+
}
|
|
190
|
+
// e. Create SquadTool entry — wrap with OTel span instrumentation at load time
|
|
191
|
+
// so skill-dispatched calls appear in traces with 'tool.skill_dispatched: true'.
|
|
192
|
+
const tool = {
|
|
193
|
+
name: toolName,
|
|
194
|
+
description: schema.description,
|
|
195
|
+
parameters: schema.parameters,
|
|
196
|
+
handler: wrapSkillHandlerWithSpan(toolName, module.default, backendConfig),
|
|
197
|
+
};
|
|
198
|
+
tools.push(tool);
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
// Failed imports are fatal (validation errors, syntax errors, etc.)
|
|
202
|
+
throw new Error(`Failed to load handler script ${scriptName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// 4. Load lifecycle.js if present
|
|
206
|
+
let lifecycle;
|
|
207
|
+
const lifecyclePath = path.join(scriptsDir, 'lifecycle.js');
|
|
208
|
+
if (existsSync(lifecyclePath)) {
|
|
209
|
+
try {
|
|
210
|
+
const lifecycleUrl = toFileUrl(lifecyclePath);
|
|
211
|
+
const lifecycleModule = await import(lifecycleUrl);
|
|
212
|
+
// Extract init and dispose named exports if they are functions
|
|
213
|
+
const init = typeof lifecycleModule.init === 'function' ? lifecycleModule.init : undefined;
|
|
214
|
+
const dispose = typeof lifecycleModule.dispose === 'function' ? lifecycleModule.dispose : undefined;
|
|
215
|
+
if (init || dispose) {
|
|
216
|
+
lifecycle = { init, dispose };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
throw new Error(`Failed to load lifecycle.js: ${err instanceof Error ? err.message : String(err)}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// 5. Return result
|
|
224
|
+
return lifecycle ? { tools, lifecycle } : { tools };
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=skill-script-loader.js.map
|