{"_id":"@artyfacts/sdk","name":"@artyfacts/sdk","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@artyfacts/sdk","version":"0.3.0","description":"SDK for uploading and managing artifacts on Artyfacts","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","bin":{"artyfacts":"dist/cli.js"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./agents":{"types":"./dist/agents/index.d.ts","import":"./dist/agents/index.mjs","require":"./dist/agents/index.js"}},"scripts":{"build":"tsup src/index.ts src/agents/index.ts --format cjs,esm --dts && tsup src/cli.ts --format cjs --no-splitting","dev":"tsup src/index.ts src/agents/index.ts --format cjs,esm --dts --watch","test":"vitest","lint":"eslint src/"},"keywords":["artyfacts","artifacts","ai","agents","llm","sdk"],"author":{"name":"Artygroup"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/artygracie/artyfacts.git","directory":"packages/sdk"},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.0.0","vitest":"^1.0.0"},"peerDependencies":{"typescript":">=4.7.0"},"peerDependenciesMeta":{"typescript":{"optional":true}},"gitHead":"f82a65d460f10b5154b4b7c3ad4b2bfb81f3481c","_id":"@artyfacts/sdk@0.3.0","bugs":{"url":"https://github.com/artygracie/artyfacts/issues"},"homepage":"https://github.com/artygracie/artyfacts#readme","_nodeVersion":"25.5.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-On4g+EqdMo6/Uiq63Rkil8hgeO+GD6pBhbRbPuCr+f9iwcD0HEPBJ/ojzQLYy9Ep8x6mC0ujFk5qpcPEC5PYLw==","shasum":"70ed9bd0de4c94171a9136c42cb99749f54c9668","tarball":"https://registry.npmjs.org/@artyfacts/sdk/-/sdk-0.3.0.tgz","fileCount":35,"unpackedSize":1016703,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAayccp6n7dzMqWem8JmkaUHJKFUjMRly/c4487ueBv0AiEAzJONYnC+MudROn6obGIKwsX/nSvxMW7V14ufqnnQW8Y="}]},"_npmUser":{"name":"artygracie","email":"gracie@artygroup.com"},"directories":{},"maintainers":[{"name":"artygracie","email":"gracie@artygroup.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.3.0_1774464974353_0.23124908658664767"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-25T18:56:14.229Z","0.3.0":"2026-03-25T18:56:14.565Z","modified":"2026-03-25T18:56:14.848Z"},"maintainers":[{"name":"artygracie","email":"gracie@artygroup.com"}],"description":"SDK for uploading and managing artifacts on Artyfacts","homepage":"https://github.com/artygracie/artyfacts#readme","keywords":["artyfacts","artifacts","ai","agents","llm","sdk"],"repository":{"type":"git","url":"git+https://github.com/artygracie/artyfacts.git","directory":"packages/sdk"},"author":{"name":"Artygroup"},"bugs":{"url":"https://github.com/artygracie/artyfacts/issues"},"license":"MIT","readme":"# @artyfacts/sdk\n\nTypeScript SDK for integrating AI agents with Artyfacts — the artifact handoff and human-in-the-loop platform.\n\n## Installation\n\n```bash\nnpm install @artyfacts/sdk\n# or\npnpm add @artyfacts/sdk\n```\n\n## Quick Start\n\n### For Clawdbot Agents\n\n```typescript\nimport { createClawdbotAdapter } from '@artyfacts/sdk'\n\n// Initialize from environment variables\nconst agent = await createClawdbotAdapter({\n  agentId: 'engineering-agent'\n})\n\n// Get your role configuration\nconsole.log(agent.session.role.roleTitle)  // 'Engineering Agent'\nconsole.log(agent.session.systemPrompt)     // Full system prompt with capabilities\n\n// Claim and work on tasks\nconst task = await agent.claimNextTask()\nif (task) {\n  console.log(`Working on: ${task.heading}`)\n  \n  // Do the work...\n  \n  await agent.completeTask(task.id, {\n    summary: 'Implemented the feature',\n    outputUrl: 'https://github.com/org/repo/pull/123'\n  })\n}\n```\n\n### Direct SDK Usage\n\n```typescript\nimport { AgentSession } from '@artyfacts/sdk'\n\nconst session = new AgentSession({\n  apiKey: process.env.ARTYFACTS_API_KEY,\n  agentId: 'my-agent',\n})\n\nawait session.init()\n\n// Access role info\nconsole.log(session.role.name)\nconsole.log(session.role.capabilities)\nconsole.log(session.role.permissions)\n\n// Work with artifacts\nconst artifact = await session.artifacts.upload({\n  title: 'Research Report',\n  content: '# Findings\\n...',\n  tags: ['research'],\n})\n\n// Manage tasks\nconst tasks = await session.tasks.getClaimable()\nconst claimed = await session.tasks.claim(tasks[0].id)\nawait session.tasks.complete(claimed.id, { summary: 'Done!' })\n\n// Check permissions\nconst result = await session.checkPermission('code.deploy')\nif (!result.allowed && result.requiresApproval) {\n  // Wait for human approval\n  await session.requirePermission('code.deploy')\n}\n```\n\n## Core Classes\n\n### AgentSession\n\nThe main entry point for agent-Artyfacts integration.\n\n```typescript\nconst session = new AgentSession({\n  apiKey: string,              // Required: Artyfacts API key\n  agentId: string,             // Required: Agent identifier\n  baseUrl?: string,            // Default: 'https://artyfacts.dev/api/v1'\n  permissionCacheTtlMs?: number, // Default: 60000 (1 minute)\n  onApprovalRequired?: (request) => void,\n  onApprovalResolved?: (request, approved, note) => void,\n})\n\nawait session.init()  // Fetch role configuration\n```\n\n**Properties:**\n- `role` — Agent's role configuration (AgentRoleConfig)\n- `systemPrompt` — Generated system prompt with capabilities/permissions\n- `artifacts` — Artyfacts client for artifact operations\n- `tasks` — TaskQueue for task management\n- `goals` — Goals client for structured work\n- `reviews` — Reviews client for human-in-the-loop\n\n**Methods:**\n- `hasCapability(id)` — Check if agent has a capability\n- `hasPermission(permission)` — Check cached permission\n- `checkPermission(action, context?)` — Check permission with approval flow\n- `requirePermission(action, context?)` — Block until permission granted\n- `refresh()` — Reload role configuration\n\n### TaskQueue\n\nDiscover, claim, and manage tasks.\n\n```typescript\n// Get available tasks\nconst tasks = await session.tasks.getClaimable({ limit: 10 })\n\n// Claim a task\nconst task = await session.tasks.claim(taskId)\n\n// Update progress\nawait session.tasks.progress(taskId, 'Halfway done')\n\n// Block with notification\nawait session.tasks.block(taskId, 'Need design review', {\n  notify: true,\n  slackChannel: '#design-review'\n})\n\n// Unblock\nawait session.tasks.unblock(taskId, 'Design approved')\n\n// Complete with output\nawait session.tasks.complete(taskId, {\n  summary: 'Feature implemented',\n  outputUrl: 'https://github.com/org/repo/pull/123',\n  outputType: 'pull_request',\n})\n\n// Get current task\nconst current = await session.tasks.getCurrentTask()\n```\n\n### Goals\n\nStructured work management with phases and progress tracking.\n\n```typescript\n// Discover matching goals\nconst goals = await session.goals.discover('user onboarding')\n\n// List active goals\nconst active = await session.goals.list({ status: 'active' })\n\n// Create a goal\nconst goal = await session.goals.create({\n  title: 'Improve User Onboarding',\n  objective: 'Reduce time-to-value by 50%',\n  metrics: ['Activation rate', 'Day-7 retention'],\n  context: 'Current onboarding takes 15 minutes...',\n  tags: ['product', 'growth'],\n})\n\n// Add a phase with tasks\nawait session.goals.createPhase(goal.id, {\n  title: 'Phase 1: Research',\n  tasks: [\n    { title: 'User interviews', assignee: 'research-agent' },\n    { title: 'Competitor analysis', assignee: 'research-agent' },\n  ],\n})\n\n// Get progress\nconst progress = await session.goals.getWithProgress(goal.id)\nconsole.log(`${progress.progress.percent}% complete`)\n```\n\n### Reviews\n\nHuman-in-the-loop approval workflows.\n\n```typescript\n// Create a review request\nconst review = await session.reviews.create({\n  itemType: 'deployment',\n  itemTitle: 'Deploy v2.0 to production',\n  itemDescription: 'Major release with new features...',\n  urgency: 'high',\n})\n\n// Wait for decision (polls automatically)\nconst decision = await session.reviews.waitForDecision(review.id, {\n  timeoutMs: 30 * 60 * 1000,  // 30 minutes\n  onPoll: (status) => console.log(`Status: ${status}`),\n})\n\nif (decision.status === 'approved') {\n  // Proceed with deployment\n}\n\n// List pending reviews\nconst pending = await session.reviews.getPending()\n```\n\n## Permission System\n\nThe SDK includes a comprehensive permission system with approval flows.\n\n### Action → Permission Mapping\n\n```typescript\nimport { ACTION_PERMISSIONS, HIGH_RISK_ACTIONS } from '@artyfacts/sdk'\n\n// Actions map to permissions\nACTION_PERMISSIONS['artifact.create']  // 'create_artifacts'\nACTION_PERMISSIONS['code.deploy']      // 'deploy_code'\nACTION_PERMISSIONS['comms.email']      // 'external_comms'\n\n// High-risk actions trigger approval flow when denied\nHIGH_RISK_ACTIONS.has('code.deploy')   // true\nHIGH_RISK_ACTIONS.has('artifact.create') // false\n```\n\n### Checking Permissions\n\n```typescript\n// Quick check (cached)\nif (session.hasPermission('deploy_code')) {\n  // Already authorized\n}\n\n// Full check with approval flow\nconst result = await session.checkPermission('code.deploy', {\n  resourceType: 'deployment',\n  resourceId: 'prod-v2.0',\n  description: 'Deploy version 2.0 to production',\n})\n\nif (result.allowed) {\n  // Proceed\n} else if (result.requiresApproval) {\n  // Review created, waiting for human\n  console.log(`Review ID: ${result.reviewId}`)\n}\n\n// Block until approved (or throw on rejection)\nawait session.requirePermission('code.deploy')\n```\n\n## Clawdbot Integration\n\n### Tool Wrappers\n\nRegister SDK methods as Clawdbot tools:\n\n```typescript\nimport { createAllTools } from '@artyfacts/sdk'\n\nconst tools = createAllTools(session)\n\n// Tools available:\n// - artyfacts.upload, artyfacts.get, artyfacts.list, ...\n// - artyfacts.tasks.claim, artyfacts.tasks.complete, ...\n// - artyfacts.goals.discover, artyfacts.goals.create, ...\n// - artyfacts.reviews.create, artyfacts.reviews.pending, ...\n// - artyfacts.permissions.check, ...\n```\n\n### System Prompt Generation\n\n```typescript\nimport { generateSystemPrompt } from '@artyfacts/sdk'\n\nconst prompt = generateSystemPrompt(session.role, {\n  includeCapabilities: true,\n  includePermissions: true,\n  includeRestrictions: true,\n  customSections: [\n    { heading: 'Project Context', content: '...' }\n  ],\n})\n\n// Or use the getter\nconsole.log(session.systemPrompt)\n```\n\n## Environment Variables\n\n| Variable | Description | Required |\n|----------|-------------|----------|\n| `ARTYFACTS_API_KEY` | API key for authentication | Yes |\n| `ARTYFACTS_AGENT_ID` | Default agent identifier | No |\n| `ARTYFACTS_BASE_URL` | API base URL | No (defaults to production) |\n\n## Error Handling\n\n```typescript\nimport {\n  AgentSessionError,\n  PermissionDeniedError,\n  ApprovalTimeoutError,\n  TaskAlreadyClaimedError,\n  TaskNotFoundError,\n  ReviewTimeoutError,\n  GoalNotFoundError,\n} from '@artyfacts/sdk'\n\ntry {\n  await session.tasks.claim(taskId)\n} catch (error) {\n  if (error instanceof TaskAlreadyClaimedError) {\n    console.log('Task already claimed by another agent')\n  } else if (error instanceof TaskNotFoundError) {\n    console.log('Task does not exist')\n  }\n}\n\ntry {\n  await session.requirePermission('code.deploy')\n} catch (error) {\n  if (error instanceof PermissionDeniedError) {\n    console.log(`Denied: ${error.rationale}`)\n  } else if (error instanceof ApprovalTimeoutError) {\n    console.log('Approval timed out')\n  }\n}\n```\n\n## TypeScript Types\n\nAll types are exported:\n\n```typescript\nimport type {\n  // Session\n  AgentSessionConfig,\n  AgentRoleConfig,\n  AgentCapability,\n  AgentPermission,\n  \n  // Tasks\n  ClaimableTask,\n  ClaimedTask,\n  CompletedTask,\n  TaskStatusInfo,\n  \n  // Goals\n  Goal,\n  Phase,\n  GoalProgress,\n  GoalWithProgress,\n  \n  // Reviews\n  Review,\n  ReviewStatus,\n  CreateReviewOptions,\n  \n  // Permissions\n  PermissionContext,\n  PermissionResult,\n  \n  // Clawdbot\n  ClawdbotConfig,\n  ToolDefinition,\n  ToolMap,\n} from '@artyfacts/sdk'\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-9feb7034dae16bffdfa146d053993704"}