@compilr-dev/sdk 0.9.14 → 0.9.15

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.
@@ -43,7 +43,8 @@ export function createCompressorHook(config) {
43
43
  if (compressed !== null && compressed.length < stdout.length) {
44
44
  const saved = stdout.length - compressed.length;
45
45
  const pct = Math.round((saved / stdout.length) * 100);
46
- console.log(`[compressor] bash "${command.slice(0, 40)}" ${String(stdout.length)} → ${String(compressed.length)} chars (${String(pct)}% saved)`); // eslint-disable-line no-console
46
+ // eslint-disable-next-line no-console
47
+ console.log(`[compressor] bash "${command.slice(0, 40)}" ${String(stdout.length)} → ${String(compressed.length)} chars (${String(pct)}% saved)`);
47
48
  return {
48
49
  result: {
49
50
  ...ctx.result,
@@ -105,6 +105,12 @@ export function createPlanTools(config, planModeCallbacks) {
105
105
  },
106
106
  execute: async (input) => {
107
107
  try {
108
+ // Guard: prevent agent from self-approving plans during plan mode
109
+ if (input.status === 'approved' &&
110
+ planModeCallbacks?.isPlanModeActive?.()) {
111
+ return createErrorResult('Cannot set status to "approved" directly during plan mode. ' +
112
+ 'Use plan_submit to submit your plan for user approval instead.');
113
+ }
108
114
  const updateInput = {};
109
115
  if (input.content !== undefined) {
110
116
  updateInput.content = input.content;
@@ -363,7 +369,8 @@ export function createPlanTools(config, planModeCallbacks) {
363
369
  // ---------------------------------------------------------------------------
364
370
  // plan_submit (requires callback from host app)
365
371
  // ---------------------------------------------------------------------------
366
- const planSubmitTool = planModeCallbacks
372
+ const onPlanSubmitFn = planModeCallbacks?.onPlanSubmit;
373
+ const planSubmitTool = onPlanSubmitFn
367
374
  ? defineTool({
368
375
  name: 'plan_submit',
369
376
  description: 'Submit a plan for user approval. Call this when your plan is ready for review. ' +
@@ -390,7 +397,7 @@ export function createPlanTools(config, planModeCallbacks) {
390
397
  return createErrorResult(`Plan ${String(input.plan_id)} not found`);
391
398
  }
392
399
  // Call host app's approval UI
393
- const result = await planModeCallbacks.onPlanSubmit({
400
+ const result = await onPlanSubmitFn({
394
401
  planId: input.plan_id,
395
402
  summary: input.summary,
396
403
  });
@@ -414,7 +421,8 @@ export function createPlanTools(config, planModeCallbacks) {
414
421
  // ---------------------------------------------------------------------------
415
422
  // plan_mode_exit (requires callback from host app)
416
423
  // ---------------------------------------------------------------------------
417
- const planModeExitTool = planModeCallbacks
424
+ const onPlanModeExitFn = planModeCallbacks?.onPlanModeExit;
425
+ const planModeExitTool = onPlanModeExitFn
418
426
  ? defineTool({
419
427
  name: 'plan_mode_exit',
420
428
  description: 'Exit plan mode without submitting a plan. Use this when the task is simple enough ' +
@@ -430,7 +438,7 @@ export function createPlanTools(config, planModeCallbacks) {
430
438
  required: ['reason'],
431
439
  },
432
440
  execute: async (input) => {
433
- await planModeCallbacks.onPlanModeExit({ reason: input.reason });
441
+ await onPlanModeExitFn({ reason: input.reason });
434
442
  return createSuccessResult({
435
443
  message: `Exited plan mode: ${input.reason}. Full tools now available.`,
436
444
  });
@@ -112,10 +112,10 @@ Suggest delegation when a task would benefit from focused expertise.`,
112
112
  // =============================================================================
113
113
  export const generalConfig = {
114
114
  id: 'general',
115
- label: 'General',
116
- description: 'Blank project — define your own workflow',
115
+ label: 'General Purpose',
116
+ description: 'Any project — define your own workflow',
117
117
  icon: 'FolderOpen',
118
- category: 'software',
118
+ category: 'general',
119
119
  phases: [],
120
120
  suggestedAgents: [],
121
121
  documentTemplates: [
@@ -76,7 +76,7 @@ export interface ProjectTypeConfig {
76
76
  /** Lucide icon name */
77
77
  icon: string;
78
78
  /** Category for grouping in type selector */
79
- category: 'software' | 'writing' | 'business' | 'education';
79
+ category: 'general' | 'software' | 'writing' | 'business' | 'education';
80
80
  /** Workflow phases (shown in project panel lifecycle) */
81
81
  phases: ProjectPhase[];
82
82
  /** Suggested agent roles (shown first in "Add Agent" dialog) */
@@ -38,9 +38,11 @@ export interface PlanModeExitInfo {
38
38
  */
39
39
  export interface PlanModeCallbacks {
40
40
  /** Called when agent submits a plan for approval (shows approval UI) */
41
- onPlanSubmit: (info: PlanSubmitInfo) => Promise<PlanSubmitResult>;
41
+ onPlanSubmit?: (info: PlanSubmitInfo) => Promise<PlanSubmitResult>;
42
42
  /** Called when agent wants to exit plan mode without a plan */
43
- onPlanModeExit: (info: PlanModeExitInfo) => Promise<void>;
43
+ onPlanModeExit?: (info: PlanModeExitInfo) => Promise<void>;
44
+ /** Check if plan mode is currently active (used to guard plan_update from self-approval) */
45
+ isPlanModeActive?: () => boolean;
44
46
  }
45
47
  /**
46
48
  * System prompt section injected when plan mode is active.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.9.14",
3
+ "version": "0.9.15",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -62,6 +62,9 @@
62
62
  "better-sqlite3": "^11.0.0 || ^12.0.0"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
+ "@compilr-dev/agents-coding": {
66
+ "optional": true
67
+ },
65
68
  "better-sqlite3": {
66
69
  "optional": true
67
70
  }