godpowers 1.6.13 → 1.6.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.
- package/CHANGELOG.md +63 -0
- package/README.md +23 -10
- package/RELEASE.md +61 -54
- package/SKILL.md +16 -1
- package/agents/god-automation-engineer.md +103 -0
- package/agents/god-orchestrator.md +2 -1
- package/lib/automation-providers.js +189 -4
- package/lib/planning-systems.js +479 -0
- package/lib/reverse-sync.js +7 -1
- package/lib/source-sync.js +220 -0
- package/package.json +3 -3
- package/routing/god-automation-setup.yaml +1 -1
- package/routing/god-migrate.yaml +61 -0
- package/schema/state.v1.json +57 -0
- package/skills/god-automation-setup.md +39 -6
- package/skills/god-doctor.md +2 -2
- package/skills/god-init.md +10 -0
- package/skills/god-migrate.md +146 -0
- package/skills/god-sync.md +7 -2
- package/skills/god-version.md +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Godpowers Automation Providers
|
|
3
3
|
*
|
|
4
|
-
* Detects host-native automation surfaces
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Detects host-native automation surfaces, renders opt-in setup guidance, and
|
|
5
|
+
* records completed host setup after explicit confirmation. This module never
|
|
6
|
+
* creates schedules, routines, background agents, commits, pushes, packages,
|
|
7
|
+
* publishes, deploys, or clears reviews by itself.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
const fs = require('fs');
|
|
@@ -219,6 +220,82 @@ const PROVIDERS = [
|
|
|
219
220
|
}
|
|
220
221
|
];
|
|
221
222
|
|
|
223
|
+
const EXECUTION_ADAPTERS = {
|
|
224
|
+
'codex-app': {
|
|
225
|
+
method: 'host-tool-calling',
|
|
226
|
+
hostTool: 'codex_app.automation_update',
|
|
227
|
+
action: 'Call the Codex App automation tool after the user approves provider, template, cadence, and scope.'
|
|
228
|
+
},
|
|
229
|
+
'claude-routines': {
|
|
230
|
+
method: 'host-native-command',
|
|
231
|
+
hostCommand: '/schedule',
|
|
232
|
+
action: 'Use Claude Code schedule or routine creation after explicit user approval.'
|
|
233
|
+
},
|
|
234
|
+
'cline-schedule': {
|
|
235
|
+
method: 'local-command',
|
|
236
|
+
localCommand: 'cline schedule',
|
|
237
|
+
action: 'Use the Cline scheduler after explicit user approval.'
|
|
238
|
+
},
|
|
239
|
+
'kilo-scheduled-triggers': {
|
|
240
|
+
method: 'host-native-ui',
|
|
241
|
+
action: 'Use KiloClaw Scheduled Triggers after explicit user approval.'
|
|
242
|
+
},
|
|
243
|
+
'qwen-loop': {
|
|
244
|
+
method: 'session-command',
|
|
245
|
+
hostCommand: '/loop',
|
|
246
|
+
action: 'Use Qwen Code loop only for session-scoped recurring checks.'
|
|
247
|
+
},
|
|
248
|
+
'cursor-background-agent': {
|
|
249
|
+
method: 'background-agent',
|
|
250
|
+
action: 'Use Cursor Background Agent mode or API for branch-scoped asynchronous work.'
|
|
251
|
+
},
|
|
252
|
+
'github-copilot-cloud-agent': {
|
|
253
|
+
method: 'background-agent',
|
|
254
|
+
action: 'Use GitHub issue, pull request, or Copilot cloud agent entry points for branch-scoped work.'
|
|
255
|
+
},
|
|
256
|
+
'windsurf-workflows': {
|
|
257
|
+
method: 'manual-workflow',
|
|
258
|
+
action: 'Install or select a Windsurf workflow manually because durable scheduling is not confirmed.'
|
|
259
|
+
},
|
|
260
|
+
'gemini-headless': {
|
|
261
|
+
method: 'scriptable-headless',
|
|
262
|
+
localCommand: 'gemini -p',
|
|
263
|
+
action: 'Use Gemini CLI headless execution only with an approved host, CI, or OS scheduler.'
|
|
264
|
+
},
|
|
265
|
+
'opencode-run': {
|
|
266
|
+
method: 'scriptable-headless',
|
|
267
|
+
localCommand: 'opencode run',
|
|
268
|
+
action: 'Use OpenCode run or serve only with an approved host, CI, or OS scheduler.'
|
|
269
|
+
},
|
|
270
|
+
'augment-subagents': {
|
|
271
|
+
method: 'manual-workflow',
|
|
272
|
+
action: 'Use Augment Agent, Agent Auto, or subagents manually unless a native scheduler is confirmed.'
|
|
273
|
+
},
|
|
274
|
+
'codebuddy-sdk': {
|
|
275
|
+
method: 'scriptable-headless',
|
|
276
|
+
action: 'Use CodeBuddy SDK only with an approved host, CI, or OS scheduler.'
|
|
277
|
+
},
|
|
278
|
+
'pi-sdk': {
|
|
279
|
+
method: 'scriptable-headless',
|
|
280
|
+
action: 'Use Pi CLI or SDK only with an approved host, CI, or OS scheduler.'
|
|
281
|
+
},
|
|
282
|
+
trae: {
|
|
283
|
+
method: 'unsupported',
|
|
284
|
+
action: 'Report scheduled automation as unknown until Trae exposes a confirmed provider.'
|
|
285
|
+
},
|
|
286
|
+
antigravity: {
|
|
287
|
+
method: 'unsupported',
|
|
288
|
+
action: 'Report scheduled automation as unknown until Antigravity exposes a confirmed provider.'
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const EXECUTION_GUARDRAILS = [
|
|
293
|
+
'Ask for explicit approval before creating, updating, triggering, pausing, resuming, or deleting host automations.',
|
|
294
|
+
'Use direct host tool calling only for one read-only template with a known provider and approved cadence.',
|
|
295
|
+
'Spawn god-automation-engineer for multiple templates, write-capable automation, background agents, scriptable schedulers, or provider uncertainty.',
|
|
296
|
+
'Write .godpowers/automations.json only after host setup succeeds.'
|
|
297
|
+
];
|
|
298
|
+
|
|
222
299
|
function detect(projectRoot = process.cwd(), opts = {}) {
|
|
223
300
|
const ctx = {
|
|
224
301
|
projectRoot,
|
|
@@ -298,9 +375,12 @@ function render(report) {
|
|
|
298
375
|
function setupPlan(projectRoot = process.cwd(), opts = {}) {
|
|
299
376
|
const report = detect(projectRoot, opts);
|
|
300
377
|
const provider = report.recommendedProvider;
|
|
378
|
+
const selectedTemplates = selectTemplates(report.safeTemplates, opts.templates);
|
|
301
379
|
return {
|
|
302
380
|
...report,
|
|
303
|
-
|
|
381
|
+
selectedTemplates,
|
|
382
|
+
setup: provider ? provider.setup : ['No automation provider is available. Use /god-next or godpowers next --project . manually.'],
|
|
383
|
+
execution: buildExecutionPlan(projectRoot, provider, selectedTemplates, opts)
|
|
304
384
|
};
|
|
305
385
|
}
|
|
306
386
|
|
|
@@ -316,6 +396,13 @@ function renderSetupPlan(plan) {
|
|
|
316
396
|
'Setup steps:',
|
|
317
397
|
...plan.setup.map((step, index) => ` ${index + 1}. ${step}`),
|
|
318
398
|
'',
|
|
399
|
+
'Execution path:',
|
|
400
|
+
` - Method: ${plan.execution.method}`,
|
|
401
|
+
` - Action: ${plan.execution.action}`,
|
|
402
|
+
` - Direct host tool calling: ${plan.execution.directHostToolCalling ? 'available after approval' : 'not available'}`,
|
|
403
|
+
` - Specialist agent: ${plan.execution.specialistAgent || 'not required for simple read-only setup'}`,
|
|
404
|
+
` - Record after success: ${plan.execution.recordPath}`,
|
|
405
|
+
'',
|
|
319
406
|
'Recommended safe templates:',
|
|
320
407
|
...plan.safeTemplates.map(template => ` - ${template.id}: ${template.prompt}`),
|
|
321
408
|
'',
|
|
@@ -326,6 +413,100 @@ function renderSetupPlan(plan) {
|
|
|
326
413
|
].join('\n');
|
|
327
414
|
}
|
|
328
415
|
|
|
416
|
+
function selectTemplates(safeTemplates, selectedIds) {
|
|
417
|
+
if (!Array.isArray(selectedIds) || selectedIds.length === 0) {
|
|
418
|
+
const daily = safeTemplates.find(template => template.id === 'daily-status');
|
|
419
|
+
return daily ? [daily] : safeTemplates.slice(0, 1);
|
|
420
|
+
}
|
|
421
|
+
const selected = [];
|
|
422
|
+
for (const id of selectedIds) {
|
|
423
|
+
const found = safeTemplates.find(template => template.id === id);
|
|
424
|
+
if (found) selected.push(found);
|
|
425
|
+
}
|
|
426
|
+
return selected;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function buildExecutionPlan(projectRoot, provider, selectedTemplates, opts = {}) {
|
|
430
|
+
if (!provider) {
|
|
431
|
+
return {
|
|
432
|
+
method: 'manual',
|
|
433
|
+
action: 'No provider is available. Run Godpowers commands manually.',
|
|
434
|
+
directHostToolCalling: false,
|
|
435
|
+
hostTool: null,
|
|
436
|
+
hostCommand: null,
|
|
437
|
+
localCommand: null,
|
|
438
|
+
specialistAgent: null,
|
|
439
|
+
approvalRequired: true,
|
|
440
|
+
recordPath: path.join(projectRoot, CONFIG_PATH),
|
|
441
|
+
guardrails: EXECUTION_GUARDRAILS.slice()
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const adapter = EXECUTION_ADAPTERS[provider.id] || {
|
|
446
|
+
method: provider.class,
|
|
447
|
+
action: 'Use the provider-native setup surface after explicit user approval.'
|
|
448
|
+
};
|
|
449
|
+
const writeCapable = Boolean(opts.writeCapable);
|
|
450
|
+
const complex = writeCapable ||
|
|
451
|
+
selectedTemplates.length > 1 ||
|
|
452
|
+
provider.class === 'background-agent' ||
|
|
453
|
+
provider.class === 'scriptable-headless' ||
|
|
454
|
+
provider.class === 'unknown';
|
|
455
|
+
const directHostToolCalling = !complex && (
|
|
456
|
+
adapter.method === 'host-tool-calling' ||
|
|
457
|
+
adapter.method === 'host-native-command' ||
|
|
458
|
+
adapter.method === 'local-command' ||
|
|
459
|
+
adapter.method === 'session-command'
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
method: adapter.method,
|
|
464
|
+
action: adapter.action,
|
|
465
|
+
directHostToolCalling,
|
|
466
|
+
hostTool: adapter.hostTool || null,
|
|
467
|
+
hostCommand: adapter.hostCommand || null,
|
|
468
|
+
localCommand: adapter.localCommand || null,
|
|
469
|
+
specialistAgent: complex ? 'god-automation-engineer' : null,
|
|
470
|
+
approvalRequired: true,
|
|
471
|
+
recordPath: path.join(projectRoot, CONFIG_PATH),
|
|
472
|
+
guardrails: EXECUTION_GUARDRAILS.slice()
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function buildAutomationRecord(providerId, templateId, opts = {}) {
|
|
477
|
+
const provider = PROVIDERS.find(item => item.id === providerId);
|
|
478
|
+
const template = SAFE_TEMPLATES.find(item => item.id === templateId);
|
|
479
|
+
if (!provider) throw new Error(`unknown automation provider: ${providerId}`);
|
|
480
|
+
if (!template) throw new Error(`unknown automation template: ${templateId}`);
|
|
481
|
+
return {
|
|
482
|
+
id: template.id,
|
|
483
|
+
provider: provider.id,
|
|
484
|
+
status: opts.status || 'active',
|
|
485
|
+
cadence: opts.cadence || template.cadence,
|
|
486
|
+
summary: opts.summary || template.prompt,
|
|
487
|
+
risk: template.risk,
|
|
488
|
+
createdAt: opts.createdAt || new Date().toISOString(),
|
|
489
|
+
host: opts.host || provider.label,
|
|
490
|
+
hostId: opts.hostId || null,
|
|
491
|
+
hostSurface: opts.hostSurface || (EXECUTION_ADAPTERS[provider.id] && EXECUTION_ADAPTERS[provider.id].method) || provider.class
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function recordAutomation(projectRoot, record, opts = {}) {
|
|
496
|
+
if (!opts.confirmedHostSuccess) {
|
|
497
|
+
throw new Error('confirmedHostSuccess is required before recording automation');
|
|
498
|
+
}
|
|
499
|
+
const file = path.join(projectRoot, CONFIG_PATH);
|
|
500
|
+
const config = readConfig(projectRoot);
|
|
501
|
+
const next = config.automations.filter(item =>
|
|
502
|
+
!(item.id === record.id && item.provider === record.provider)
|
|
503
|
+
);
|
|
504
|
+
next.push(record);
|
|
505
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
506
|
+
fs.writeFileSync(file, `${JSON.stringify({ automations: next }, null, 2)}\n`);
|
|
507
|
+
return { automations: next };
|
|
508
|
+
}
|
|
509
|
+
|
|
329
510
|
function readConfig(projectRoot) {
|
|
330
511
|
const file = path.join(projectRoot, CONFIG_PATH);
|
|
331
512
|
if (!fs.existsSync(file)) return { automations: [] };
|
|
@@ -407,5 +588,9 @@ module.exports = {
|
|
|
407
588
|
render,
|
|
408
589
|
setupPlan,
|
|
409
590
|
renderSetupPlan,
|
|
591
|
+
selectTemplates,
|
|
592
|
+
buildExecutionPlan,
|
|
593
|
+
buildAutomationRecord,
|
|
594
|
+
recordAutomation,
|
|
410
595
|
readConfig
|
|
411
596
|
};
|