@compilr-dev/sdk 0.13.0 → 0.15.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.
@@ -14,7 +14,11 @@ export const ACTION_REGISTRY = [
14
14
  icon: 'Wand2',
15
15
  applicableTo: ['project'],
16
16
  category: 'design',
17
- suggestedRole: 'architect',
17
+ // BA owns requirements: the 'ba' role (analyst profile) has both
18
+ // backlog_write and documents, so it can complete the full /design action
19
+ // (create work items + write the PRD). The architect profile lacks
20
+ // backlog_write and cannot create the backlog.
21
+ suggestedRole: 'ba',
18
22
  needsInput: true,
19
23
  inputPrompt: 'What would you like to design?',
20
24
  },
@@ -34,8 +38,13 @@ export const ACTION_REGISTRY = [
34
38
  description: 'Create a product requirements document',
35
39
  icon: 'FileText',
36
40
  applicableTo: ['project'],
37
- category: 'planning',
38
- suggestedRole: 'pm',
41
+ // PRD is artifact-authoring (requirements), grouped with design/architecture
42
+ // rather than backlog-breakdown 'planning' (refine/refine-item).
43
+ category: 'design',
44
+ // Requirements work → Business Analyst, not PM. The 'ba' role (analyst
45
+ // profile) is purpose-built for requirements gathering and has the
46
+ // documents tools needed to author the PRD.
47
+ suggestedRole: 'ba',
39
48
  },
40
49
  {
41
50
  id: 'architecture',
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Agent-error classification.
3
+ *
4
+ * Provider/agent failures surface to hosts in two shapes:
5
+ * - as a thrown `ProviderError` instance (in-process — e.g. the CLI), or
6
+ * - as a stringified message after crossing an IPC/serialization boundary
7
+ * (e.g. the Desktop app's `agent.chat` IPC returns `error: string`).
8
+ *
9
+ * Hosts were string-matching the message independently to detect the common
10
+ * first-run failure (a missing/invalid API key → 401), which is duplicated and
11
+ * fragile. This centralizes the classification so every host shares one
12
+ * implementation; the *remediation copy* stays host-specific (the CLI tells the
13
+ * user to run /config or set an env var; Desktop points to Settings).
14
+ */
15
+ export type AgentErrorCategory = 'auth' | 'rate_limit' | 'overloaded' | 'server' | 'connection' | 'unknown';
16
+ export interface AgentErrorInfo {
17
+ category: AgentErrorCategory;
18
+ /** HTTP status code if one could be determined. */
19
+ statusCode?: number;
20
+ /** The original message text (for logging / fallback display). */
21
+ raw: string;
22
+ }
23
+ /**
24
+ * Classify an agent/provider error into a stable category. Accepts a thrown
25
+ * `ProviderError` instance (read by duck-typing its `statusCode`), any `Error`,
26
+ * or a stringified message (post-IPC).
27
+ */
28
+ export declare function classifyAgentError(err: unknown): AgentErrorInfo;
29
+ /** Convenience: true when the failure is a missing/invalid API key. */
30
+ export declare function isApiKeyError(err: unknown): boolean;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Agent-error classification.
3
+ *
4
+ * Provider/agent failures surface to hosts in two shapes:
5
+ * - as a thrown `ProviderError` instance (in-process — e.g. the CLI), or
6
+ * - as a stringified message after crossing an IPC/serialization boundary
7
+ * (e.g. the Desktop app's `agent.chat` IPC returns `error: string`).
8
+ *
9
+ * Hosts were string-matching the message independently to detect the common
10
+ * first-run failure (a missing/invalid API key → 401), which is duplicated and
11
+ * fragile. This centralizes the classification so every host shares one
12
+ * implementation; the *remediation copy* stays host-specific (the CLI tells the
13
+ * user to run /config or set an env var; Desktop points to Settings).
14
+ */
15
+ /** Pull a usable message string out of any thrown value. */
16
+ function messageOf(err) {
17
+ if (typeof err === 'string')
18
+ return err;
19
+ if (err instanceof Error)
20
+ return err.message;
21
+ if (err && typeof err === 'object' && 'message' in err) {
22
+ return String(err.message);
23
+ }
24
+ return String(err);
25
+ }
26
+ /**
27
+ * First HTTP status code in the text, if any (e.g. "ProviderError: 401 ...").
28
+ * Uses a curated set of codes providers actually return, so a port number or IP
29
+ * octet isn't misread as a status (e.g. `ECONNREFUSED 127.0.0.1:443` must not
30
+ * read as 443 — that would mask a connection error as an HTTP one).
31
+ */
32
+ function statusFromText(text) {
33
+ const m = text.match(/\b(400|401|403|404|408|409|413|422|429|500|502|503|504|529)\b/);
34
+ return m ? Number(m[1]) : undefined;
35
+ }
36
+ function categorize(statusCode, text) {
37
+ const lower = text.toLowerCase();
38
+ // Auth: key issues. Match on status OR the provider's textual markers, since a
39
+ // stringified error may not preserve the numeric code.
40
+ if (statusCode === 401 ||
41
+ statusCode === 403 ||
42
+ /authentication_error|invalid x-api-key|invalid api key|no api key|x-api-key|permission_error|unauthorized/.test(lower)) {
43
+ return 'auth';
44
+ }
45
+ if (statusCode === 429 || /rate.?limit|too many requests/.test(lower))
46
+ return 'rate_limit';
47
+ if (statusCode === 529 || /overloaded/.test(lower))
48
+ return 'overloaded';
49
+ if ((statusCode !== undefined && statusCode >= 500 && statusCode < 600) ||
50
+ /internal server error/.test(lower)) {
51
+ return 'server';
52
+ }
53
+ if (statusCode === undefined &&
54
+ /econnrefused|econnreset|etimedout|enotfound|network|socket|dns|connection/.test(lower)) {
55
+ return 'connection';
56
+ }
57
+ return 'unknown';
58
+ }
59
+ /**
60
+ * Classify an agent/provider error into a stable category. Accepts a thrown
61
+ * `ProviderError` instance (read by duck-typing its `statusCode`), any `Error`,
62
+ * or a stringified message (post-IPC).
63
+ */
64
+ export function classifyAgentError(err) {
65
+ const raw = messageOf(err);
66
+ // A thrown ProviderError carries a numeric `statusCode`; prefer it. Fall back
67
+ // to parsing a status out of the message text (the stringified/IPC case).
68
+ let statusCode;
69
+ if (err && typeof err === 'object' && 'statusCode' in err && typeof err.statusCode === 'number') {
70
+ statusCode = err.statusCode;
71
+ }
72
+ else {
73
+ statusCode = statusFromText(raw);
74
+ }
75
+ return { category: categorize(statusCode, raw), statusCode, raw };
76
+ }
77
+ /** Convenience: true when the failure is a missing/invalid API key. */
78
+ export function isApiKeyError(err) {
79
+ return classifyAgentError(err).category === 'auth';
80
+ }
package/dist/index.d.ts CHANGED
@@ -78,6 +78,8 @@ export { PROJECT_TYPES, getProjectTypeConfig, getEnrichedProjectTypeConfig, getP
78
78
  export type { ActionMeta, SkillMeta } from './project-types/index.js';
79
79
  export type { ProjectTypeConfig, ProjectPhase, SuggestedAgent, DocumentTemplate, } from './project-types/index.js';
80
80
  export { defineTool, createSuccessResult, createErrorResult, mergeHooks, createLoggingHooks, createClaudeProvider, createOpenAIProvider, createGeminiNativeProvider, createOllamaProvider, createTogetherProvider, createGroqProvider, createFireworksProvider, createPerplexityProvider, createOpenRouterProvider, createMockProvider, MockProvider, Agent, ContextManager, DEFAULT_CONTEXT_CONFIG, createTaskTool, createSuggestTool, defaultAgentTypes, TOOL_SETS, BUILTIN_GUARDRAILS, TOOL_NAMES, getDefaultShellManager, builtinSkills, AnchorManager, MCPManager, AgentError, ProviderError, ToolError, ToolTimeoutError, MaxIterationsError, AbortError, } from '@compilr-dev/agents';
81
+ export { classifyAgentError, isApiKeyError } from './errors/classify.js';
82
+ export type { AgentErrorCategory, AgentErrorInfo } from './errors/classify.js';
81
83
  export type { Tool, HooksConfig, AgentEvent, Message, LLMProvider, AnchorInput, ToolExecutionResult, AgentRunResult, PermissionHandler, PermissionHandlerResponse, ToolPermission, AgentTypeConfig, GuardrailTriggeredHandler, BeforeLLMHookResult, BeforeToolHook, BeforeToolHookResult, AfterToolHook, AgentState, AgentConfig, SessionInfo, Anchor, AnchorScope, AnchorClearOptions, AnchorPriority, AnchorQueryOptions, FileAccessType, FileAccess, GuardrailResult, GuardrailContext, MCPClient, MCPToolDefinition, } from '@compilr-dev/agents';
82
84
  export { DEFAULT_PERMISSION_RULES, WRITE_TOOLS, findMatchingRule, permissionModeLabel, permissionLevelLabel, } from './permissions.js';
83
85
  export type { PermissionRule, PermissionMode, PermissionLevel } from './permissions.js';
package/dist/index.js CHANGED
@@ -193,6 +193,9 @@ AnchorManager,
193
193
  MCPManager,
194
194
  // Error types
195
195
  AgentError, ProviderError, ToolError, ToolTimeoutError, MaxIterationsError, AbortError, } from '@compilr-dev/agents';
196
+ // Error classification — shared by hosts to map provider/agent failures
197
+ // (esp. missing/invalid API key) into stable categories + host-specific copy.
198
+ export { classifyAgentError, isApiKeyError } from './errors/classify.js';
196
199
  // =============================================================================
197
200
  // Shared Permission Defaults & Utilities
198
201
  // =============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,6 +17,10 @@
17
17
  "./flow-runner": {
18
18
  "types": "./dist/flow-runner/index.d.ts",
19
19
  "import": "./dist/flow-runner/index.js"
20
+ },
21
+ "./errors": {
22
+ "types": "./dist/errors/classify.d.ts",
23
+ "import": "./dist/errors/classify.js"
20
24
  }
21
25
  },
22
26
  "files": [
@@ -64,7 +68,7 @@
64
68
  "node": ">=20.0.0"
65
69
  },
66
70
  "dependencies": {
67
- "@compilr-dev/agents": "^0.5.9",
71
+ "@compilr-dev/agents": "^0.6.0",
68
72
  "@compilr-dev/logger": "^0.1.0",
69
73
  "ajv": "^6.14.0",
70
74
  "yaml": "^2.8.4"