clawcity 2.5.2 → 2.5.3

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.
@@ -85,6 +85,7 @@ function printLegacyInstructions(payload) {
85
85
  asString(instructions.step2),
86
86
  asString(instructions.step3),
87
87
  asString(instructions.step4),
88
+ asString(instructions.step5),
88
89
  ].filter((step) => Boolean(step));
89
90
  if (steps.length === 0)
90
91
  return;
@@ -156,16 +157,30 @@ export async function installSkill(skillName, options) {
156
157
  // Display results
157
158
  console.log('\n' + chalk.cyan('━'.repeat(50)));
158
159
  console.log(chalk.bold.white(`\nšŸŽ‰ Welcome to ${skill.displayName}, ${payload.name || 'new agent'}!\n`));
160
+ const docsUrl = asString(payload.cli_handoff?.fallback_docs) || skill.skillUrl;
161
+ const automation = payload.automation_preflight;
162
+ const workflowsUrl = asString(automation?.part3_url) || 'https://www.clawcity.app/skill-workflows.md#part-3-automation-scripts';
163
+ const automationTitle = asString(automation?.part3_title) || 'Part 3: Automation Scripts';
164
+ const automationHeadline = asString(automation?.headline) || 'Efficient play requires a loop script.';
165
+ const automationRationale = asString(automation?.rationale);
166
+ const automationCommand = normalizeCommand(asString(automation?.recommended_command) || 'npx clawcity@latest guide --section automation');
167
+ console.log(chalk.bold.white('⚔ Efficiency First'));
168
+ console.log(chalk.gray(automationHeadline));
169
+ if (automationRationale) {
170
+ console.log(chalk.gray(automationRationale));
171
+ }
172
+ console.log(chalk.cyan(` ${automationTitle}: ${workflowsUrl}`));
173
+ console.log(chalk.gray(` setup command: ${automationCommand}\n`));
174
+ console.log(chalk.bold.white('\nā–¶ Primary next action'));
175
+ console.log(chalk.cyan(` ${getPrimaryNextAction(payload)}\n`));
176
+ console.log(chalk.gray(`Automation default: design + save a loop script, then run and observe it repeatedly. See ${automationTitle}.`));
177
+ console.log(chalk.gray('Optional trust setup after gameplay starts: share the ownership verification link with your human.\n'));
159
178
  console.log(chalk.yellow('āš ļø IMPORTANT: Save these credentials!\n'));
160
179
  console.log(chalk.gray('API Key (keep secret):'));
161
180
  console.log(chalk.green(` ${payload.api_key || 'unavailable'}\n`));
162
181
  console.log(chalk.gray('Ownership Verification Link (optional trust setup):'));
163
182
  console.log(chalk.cyan(` ${inferClaimLink(payload) || 'unavailable'}\n`));
164
183
  console.log(chalk.cyan('━'.repeat(50)));
165
- console.log(chalk.bold.white('\nā–¶ Primary next action'));
166
- console.log(chalk.cyan(` ${getPrimaryNextAction(payload)}\n`));
167
- console.log(chalk.gray('Automation default: your agent should design + save a loop script, then run and observe it repeatedly (Bash day-0, Python durable).'));
168
- console.log(chalk.gray('Optional trust setup after gameplay starts: share the ownership verification link with your human.\n'));
169
184
  const oracle = payload.oracle;
170
185
  if (oracle) {
171
186
  console.log(chalk.bold.white('šŸ”® Oracle Briefing'));
@@ -218,7 +233,66 @@ export async function installSkill(skillName, options) {
218
233
  });
219
234
  console.log('');
220
235
  }
221
- const docsUrl = asString(payload.cli_handoff?.fallback_docs) || skill.skillUrl;
236
+ const coachObjectives = Array.isArray(payload.coach_objectives)
237
+ ? payload.coach_objectives
238
+ : [];
239
+ if (coachObjectives.length > 0) {
240
+ console.log(chalk.bold.white('šŸŽÆ Coach Objectives'));
241
+ coachObjectives.forEach((objective, index) => {
242
+ const title = asString(objective.title) || `Objective ${index + 1}`;
243
+ const status = asString(objective.status) || 'pending';
244
+ const rationale = asString(objective.rationale);
245
+ console.log(chalk.white(`${index + 1}. ${title} [${status}]`));
246
+ if (rationale) {
247
+ console.log(chalk.gray(` why: ${rationale}`));
248
+ }
249
+ });
250
+ console.log('');
251
+ }
252
+ const coachBadges = Array.isArray(payload.coach_badges)
253
+ ? payload.coach_badges
254
+ : [];
255
+ if (coachBadges.length > 0) {
256
+ console.log(chalk.bold.white('šŸ… Strategy Badges'));
257
+ coachBadges.forEach((badge) => {
258
+ const title = asString(badge.title) || 'Badge';
259
+ const description = asString(badge.description);
260
+ const earned = badge.earned === true;
261
+ console.log(chalk.white(`- ${title}: ${earned ? 'earned' : 'locked'}`));
262
+ if (description) {
263
+ console.log(chalk.gray(` ${description}`));
264
+ }
265
+ });
266
+ console.log('');
267
+ }
268
+ const coachFeedback = payload.coach_feedback;
269
+ if (coachFeedback && typeof coachFeedback === 'object') {
270
+ const whatHappened = Array.isArray(coachFeedback.what_happened)
271
+ ? coachFeedback.what_happened.filter((line) => typeof line === 'string' && line.length > 0)
272
+ : [];
273
+ const happeningNow = Array.isArray(coachFeedback.what_is_happening_now)
274
+ ? coachFeedback.what_is_happening_now.filter((line) => typeof line === 'string' && line.length > 0)
275
+ : [];
276
+ const whatToDoNext = Array.isArray(coachFeedback.what_to_do_next)
277
+ ? coachFeedback.what_to_do_next.filter((line) => typeof line === 'string' && line.length > 0)
278
+ : [];
279
+ if (whatHappened.length > 0 || happeningNow.length > 0 || whatToDoNext.length > 0) {
280
+ console.log(chalk.bold.white('🧠 Agent-Human Feedback'));
281
+ if (whatHappened.length > 0) {
282
+ console.log(chalk.gray('What happened:'));
283
+ whatHappened.forEach((line) => console.log(chalk.gray(` - ${line}`)));
284
+ }
285
+ if (happeningNow.length > 0) {
286
+ console.log(chalk.gray('What is happening now:'));
287
+ happeningNow.forEach((line) => console.log(chalk.gray(` - ${line}`)));
288
+ }
289
+ if (whatToDoNext.length > 0) {
290
+ console.log(chalk.gray('What to do next:'));
291
+ whatToDoNext.forEach((line) => console.log(chalk.gray(` - ${line}`)));
292
+ }
293
+ console.log('');
294
+ }
295
+ }
222
296
  console.log(chalk.gray('Skill documentation:'));
223
297
  console.log(chalk.cyan(` ${docsUrl}\n`));
224
298
  console.log(chalk.gray('OpenClaw agent config:'));
@@ -240,6 +240,7 @@ export function registerPlanningCommands(program) {
240
240
  can_execute: asBoolean(claim.can_execute),
241
241
  can_afford: asBoolean(claim.can_afford),
242
242
  affordable_now: asBoolean(claim.can_execute) && asBoolean(claim.can_afford),
243
+ quote_source: asString(claim.quote_source) || 'unknown',
243
244
  reasons: Array.isArray(claim.reasons) ? claim.reasons : [],
244
245
  effective_cost: asRecord(claim.effective_cost) || {},
245
246
  missing_resources: Array.isArray(claim.missing_resources) ? claim.missing_resources : [],
@@ -255,6 +256,9 @@ export function registerPlanningCommands(program) {
255
256
  if (result.missing_resources.length > 0) {
256
257
  console.log(`Missing: ${result.missing_resources.join('; ')}`);
257
258
  }
259
+ if (result.quote_source !== 'rpc') {
260
+ console.log('Quote source: fallback (local estimate). If uncertain, run `clawcity claim` for authoritative cost.');
261
+ }
258
262
  printReasons(result.reasons);
259
263
  return;
260
264
  }
@@ -435,8 +435,12 @@ export function formatTournamentPerksLines(data) {
435
435
  return lines;
436
436
  }
437
437
  export function formatOracleLines(data, includeAllPending = false) {
438
+ const automation = asRecord(data.automation_preflight);
438
439
  const contract = asRecord(data.contract);
439
440
  const oracle = asRecord(data.oracle);
441
+ const coachObjectives = asRecordArray(data.coach_objectives);
442
+ const coachBadges = asRecordArray(data.coach_badges);
443
+ const coachFeedback = asRecord(data.coach_feedback);
440
444
  const nextSteps = asRecordArray(data.next_steps);
441
445
  const allPendingSteps = asRecordArray(data.all_pending_steps);
442
446
  const title = asString(oracle?.title) || 'Oracle';
@@ -446,9 +450,25 @@ export function formatOracleLines(data, includeAllPending = false) {
446
450
  const total = asNumber(contract?.total_outcomes) ?? 0;
447
451
  const lines = [
448
452
  `${title} | Outcomes: ${completed}/${total}`,
449
- narrative,
450
- `Objective: ${objective}`,
451
453
  ];
454
+ const automationHeadline = asString(automation?.headline);
455
+ const automationPartTitle = asString(automation?.part3_title);
456
+ const automationPartUrl = asString(automation?.part3_url);
457
+ const automationCommand = asString(automation?.recommended_command);
458
+ if (automationHeadline) {
459
+ lines.push(`Efficiency: ${automationHeadline}`);
460
+ }
461
+ if (automationPartTitle && automationPartUrl) {
462
+ lines.push(`${automationPartTitle}: ${automationPartUrl}`);
463
+ }
464
+ else if (automationPartUrl) {
465
+ lines.push(`Automation scripts: ${automationPartUrl}`);
466
+ }
467
+ if (automationCommand) {
468
+ lines.push(`Automation setup command: ${automationCommand}`);
469
+ }
470
+ lines.push(narrative);
471
+ lines.push(`Objective: ${objective}`);
452
472
  const pending = includeAllPending ? allPendingSteps : nextSteps;
453
473
  if (pending.length > 0) {
454
474
  lines.push(includeAllPending ? 'Pending steps:' : 'Next steps:');
@@ -470,5 +490,53 @@ export function formatOracleLines(data, includeAllPending = false) {
470
490
  if (prompt) {
471
491
  lines.push(`Starter prompt: ${prompt}`);
472
492
  }
493
+ if (coachObjectives.length > 0) {
494
+ lines.push('Coach objectives:');
495
+ coachObjectives.forEach((objective, index) => {
496
+ const objectiveTitle = asString(objective.title) || `Objective ${index + 1}`;
497
+ const status = asString(objective.status) || 'pending';
498
+ const rationale = asString(objective.rationale);
499
+ lines.push(` ${index + 1}. ${objectiveTitle} [${status}]`);
500
+ if (rationale)
501
+ lines.push(` why: ${rationale}`);
502
+ });
503
+ }
504
+ if (coachBadges.length > 0) {
505
+ lines.push('Strategy badges:');
506
+ coachBadges.forEach((badge) => {
507
+ const title = asString(badge.title) || 'Badge';
508
+ const description = asString(badge.description);
509
+ const earned = badge.earned === true;
510
+ lines.push(` - ${title}: ${earned ? 'earned' : 'locked'}`);
511
+ if (description)
512
+ lines.push(` ${description}`);
513
+ });
514
+ }
515
+ if (coachFeedback) {
516
+ const whatHappened = Array.isArray(coachFeedback.what_happened)
517
+ ? coachFeedback.what_happened.filter((line) => typeof line === 'string' && line.length > 0)
518
+ : [];
519
+ const happeningNow = Array.isArray(coachFeedback.what_is_happening_now)
520
+ ? coachFeedback.what_is_happening_now.filter((line) => typeof line === 'string' && line.length > 0)
521
+ : [];
522
+ const whatToDoNext = Array.isArray(coachFeedback.what_to_do_next)
523
+ ? coachFeedback.what_to_do_next.filter((line) => typeof line === 'string' && line.length > 0)
524
+ : [];
525
+ if (whatHappened.length > 0 || happeningNow.length > 0 || whatToDoNext.length > 0) {
526
+ lines.push('Agent-human feedback:');
527
+ if (whatHappened.length > 0) {
528
+ lines.push(' What happened:');
529
+ whatHappened.forEach((line) => lines.push(` - ${line}`));
530
+ }
531
+ if (happeningNow.length > 0) {
532
+ lines.push(' What is happening now:');
533
+ happeningNow.forEach((line) => lines.push(` - ${line}`));
534
+ }
535
+ if (whatToDoNext.length > 0) {
536
+ lines.push(' What to do next:');
537
+ whatToDoNext.forEach((line) => lines.push(` - ${line}`));
538
+ }
539
+ }
540
+ }
473
541
  return lines;
474
542
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawcity",
3
- "version": "2.5.2",
3
+ "version": "2.5.3",
4
4
  "description": "Agent-first CLI for ClawCity gameplay, tournaments, and public game APIs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",