@hadooppei/hwcode 0.2.1 → 1.0.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.
- package/.pi/extensions/hwcode.ts +35 -2
- package/.pi/extensions/model-providers.ts +1 -2
- package/.pi/extensions/workflows/cloud/activation.ts +235 -0
- package/.pi/extensions/workflows/cloud/commands.ts +96 -0
- package/.pi/extensions/workflows/cloud/events.ts +58 -0
- package/.pi/extensions/workflows/cloud/index.ts +17 -0
- package/.pi/extensions/workflows/cloud/provider-tools.ts +127 -0
- package/.pi/extensions/workflows/cloud/runner-tools.ts +129 -0
- package/.pi/extensions/workflows/cloud/runtime.ts +97 -0
- package/.pi/extensions/workflows/cloud/shared.ts +213 -0
- package/.pi/extensions/workflows/cloud/terraform-tools.ts +126 -0
- package/.pi/extensions/workflows/vibe-sdd.ts +300 -0
- package/.pi/extensions/workflows.ts +6 -253
- package/.pi/lib/runtime/config.ts +3 -7
- package/.pi/lib/runtime/defaults.ts +20 -0
- package/.pi/lib/runtime/paths.ts +68 -0
- package/.pi/lib/runtime/session-state.ts +0 -34
- package/.pi/lib/workflow-guard.ts +8 -1
- package/.pi/lib/{cloud → workflows/cloud}/adapters.ts +7 -6
- package/.pi/lib/workflows/cloud/bundles.ts +358 -0
- package/.pi/lib/workflows/cloud/execution.ts +28 -0
- package/.pi/lib/{cloud → workflows/cloud}/process.ts +5 -3
- package/.pi/lib/workflows/cloud/remote/bootstrap.ts +23 -0
- package/.pi/lib/workflows/cloud/remote/connect.ts +83 -0
- package/.pi/lib/workflows/cloud/remote/host-key.ts +35 -0
- package/.pi/lib/workflows/cloud/remote/profiles.ts +100 -0
- package/.pi/lib/workflows/cloud/remote/ssh-transport.ts +104 -0
- package/.pi/lib/workflows/cloud/remote/workspace.ts +109 -0
- package/.pi/lib/workflows/cloud/template-save.ts +108 -0
- package/.pi/lib/workflows/cloud/templates.ts +256 -0
- package/.pi/lib/workflows/cloud/terraform/plan.ts +109 -0
- package/.pi/lib/workflows/cloud/terraform/policy.ts +36 -0
- package/.pi/lib/workflows/cloud/terraform/runner.ts +64 -0
- package/.pi/lib/{cloud-vault.ts → workflows/cloud/vault.ts} +26 -24
- package/.pi/lib/workflows/cloud/workspace.ts +37 -0
- package/.pi/lib/workflows/sdd.ts +11 -0
- package/.pi/lib/workflows/state.ts +165 -1
- package/.pi/lib/working-directory.ts +0 -58
- package/.pi/lib/workspace/access-policy.ts +2 -2
- package/.pi/skills/hwcode-cloud/SKILL.md +32 -1
- package/.pi/skills/hwcode-sdd/SKILL.md +2 -0
- package/README.md +52 -12
- package/bin/hwcode.js +2 -6
- package/package.json +8 -3
- package/.pi/extensions/cloud.ts +0 -587
- package/.pi/lib/cloud/templates.ts +0 -148
- /package/.pi/lib/{cloud-providers.ts → workflows/cloud/providers.ts} +0 -0
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { basename, join } from "node:path";
|
|
4
|
-
|
|
5
|
-
import { getCloudProvider, isCloudVendorId, type CloudVendorId } from "../cloud-providers.ts";
|
|
6
|
-
import type { WorkflowState } from "../workflows/state.ts";
|
|
7
|
-
|
|
8
|
-
export interface CloudPromptTemplate {
|
|
9
|
-
id: string;
|
|
10
|
-
description: string;
|
|
11
|
-
vendor: CloudVendorId;
|
|
12
|
-
deployCurrentProject: boolean;
|
|
13
|
-
objective: string;
|
|
14
|
-
body: string;
|
|
15
|
-
path: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function defaultCloudPromptDirectory(home = homedir()): string {
|
|
19
|
-
return join(home, ".hwcode", "cloud", "prompts");
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function slugify(value: string): string {
|
|
23
|
-
const slug = value
|
|
24
|
-
.normalize("NFKD")
|
|
25
|
-
.toLowerCase()
|
|
26
|
-
.replace(/[^a-z0-9]+/gu, "-")
|
|
27
|
-
.replace(/^-+|-+$/gu, "")
|
|
28
|
-
.slice(0, 48);
|
|
29
|
-
return slug || `task-${new Date().toISOString().slice(0, 10)}`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function frontmatterValue(text: string, key: string): string | undefined {
|
|
33
|
-
const line = text.match(new RegExp(`^${key}:\\s*(.+)$`, "mu"))?.[1]?.trim();
|
|
34
|
-
if (!line) return undefined;
|
|
35
|
-
try {
|
|
36
|
-
const value = JSON.parse(line) as unknown;
|
|
37
|
-
return typeof value === "string" ? value : String(value);
|
|
38
|
-
} catch {
|
|
39
|
-
return line.replace(/^['"]|['"]$/gu, "");
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function parseCloudPromptTemplate(path: string): CloudPromptTemplate | undefined {
|
|
44
|
-
const text = readFileSync(path, "utf8");
|
|
45
|
-
const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/u);
|
|
46
|
-
if (!match) return undefined;
|
|
47
|
-
const metadata = match[1];
|
|
48
|
-
const vendorValue = frontmatterValue(metadata, "hwcode-cloud-vendor");
|
|
49
|
-
if (!vendorValue || !isCloudVendorId(vendorValue)) return undefined;
|
|
50
|
-
const id = basename(path, ".md");
|
|
51
|
-
return {
|
|
52
|
-
id,
|
|
53
|
-
description: frontmatterValue(metadata, "description") ?? id,
|
|
54
|
-
vendor: vendorValue,
|
|
55
|
-
deployCurrentProject: frontmatterValue(metadata, "hwcode-cloud-deploy") === "true",
|
|
56
|
-
objective: frontmatterValue(metadata, "hwcode-cloud-objective") ?? "",
|
|
57
|
-
body: match[2].trim(),
|
|
58
|
-
path,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function listCloudPromptTemplates(
|
|
63
|
-
directory = defaultCloudPromptDirectory(),
|
|
64
|
-
): CloudPromptTemplate[] {
|
|
65
|
-
if (!existsSync(directory)) return [];
|
|
66
|
-
return readdirSync(directory, { withFileTypes: true })
|
|
67
|
-
.filter((entry) => entry.isFile() && entry.name.endsWith(".md"))
|
|
68
|
-
.map((entry) => parseCloudPromptTemplate(join(directory, entry.name)))
|
|
69
|
-
.filter((template): template is CloudPromptTemplate => Boolean(template))
|
|
70
|
-
.sort((left, right) => left.description.localeCompare(right.description));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function expandCloudPromptTemplate(template: CloudPromptTemplate, argumentsText: string): string {
|
|
74
|
-
const value = argumentsText.trim();
|
|
75
|
-
return template.body.replace(/\$\{@:-([^}]*)\}/gu, (_match, fallback: string) => value || fallback);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function inlineCode(value: string): string {
|
|
79
|
-
return value.replace(/[\r\n]+/gu, " ").replaceAll("`", "\\`");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function renderCloudPromptTemplate(state: WorkflowState, notes = ""): string {
|
|
83
|
-
if (state.mode !== "cloud" || !state.details) throw new Error("Cloud workflow state is required");
|
|
84
|
-
const details = state.details;
|
|
85
|
-
if (details.successfulSteps.length === 0) {
|
|
86
|
-
throw new Error("No successful Cloud execution steps are available to summarize");
|
|
87
|
-
}
|
|
88
|
-
const provider = getCloudProvider(details.vendor);
|
|
89
|
-
const steps = details.successfulSteps.map((step, index) => (
|
|
90
|
-
`${index + 1}. [${step.operation}] ${step.intent}\n`
|
|
91
|
-
+ ` - Approach: ${step.approach}\n`
|
|
92
|
-
+ ` - Reference command: \`${inlineCode([step.command, ...step.args].join(" "))}\``
|
|
93
|
-
)).join("\n");
|
|
94
|
-
return [
|
|
95
|
-
"Execute a reusable HWCode Cloud task based on a previously successful run.",
|
|
96
|
-
"",
|
|
97
|
-
`Preferred provider: ${provider.label}`,
|
|
98
|
-
`Deploy current project: ${details.deployCurrentProject ? "yes" : "no"}`,
|
|
99
|
-
`Objective pattern: ${details.request}`,
|
|
100
|
-
"",
|
|
101
|
-
"Known successful execution sequence (reference only; re-check current account state before reuse):",
|
|
102
|
-
steps,
|
|
103
|
-
"",
|
|
104
|
-
...(notes ? ["Validated-run notes and pitfalls:", notes, ""] : []),
|
|
105
|
-
"Start with read-only discovery and adapt account, region, project, resource names, versions, and paths to the current environment. Present the plan and obtain all normal HWCode Cloud approvals. Never copy credentials or assume resources from the previous run still exist.",
|
|
106
|
-
"If HWCode Cloud is not active, do not run cloud commands directly; ask the user to start this template through /hwcode-cloud-template.",
|
|
107
|
-
"",
|
|
108
|
-
"Additional instructions: ${@:-Use the objective and successful sequence above.}",
|
|
109
|
-
].join("\n");
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function saveCloudPromptTemplate(
|
|
113
|
-
requestedName: string,
|
|
114
|
-
state: WorkflowState,
|
|
115
|
-
directory = defaultCloudPromptDirectory(),
|
|
116
|
-
notes = "",
|
|
117
|
-
): CloudPromptTemplate {
|
|
118
|
-
if (state.mode !== "cloud" || !state.details) throw new Error("Cloud workflow state is required");
|
|
119
|
-
const idBase = `hwcloud-${slugify(requestedName || state.details.request)}`;
|
|
120
|
-
const body = renderCloudPromptTemplate(state, notes);
|
|
121
|
-
const description = `Reuse successful ${getCloudProvider(state.details.vendor).label} workflow: ${state.details.request.slice(0, 80)}`;
|
|
122
|
-
const content = [
|
|
123
|
-
"---",
|
|
124
|
-
`description: ${JSON.stringify(description)}`,
|
|
125
|
-
'argument-hint: "[additional instructions]"',
|
|
126
|
-
`hwcode-cloud-vendor: ${JSON.stringify(state.details.vendor)}`,
|
|
127
|
-
`hwcode-cloud-deploy: ${state.details.deployCurrentProject}`,
|
|
128
|
-
`hwcode-cloud-objective: ${JSON.stringify(state.details.request)}`,
|
|
129
|
-
"---",
|
|
130
|
-
body,
|
|
131
|
-
"",
|
|
132
|
-
].join("\n");
|
|
133
|
-
|
|
134
|
-
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
135
|
-
chmodSync(directory, 0o700);
|
|
136
|
-
let id = idBase;
|
|
137
|
-
let path = join(directory, `${id}.md`);
|
|
138
|
-
for (let suffix = 2; existsSync(path); suffix++) {
|
|
139
|
-
id = `${idBase}-${suffix}`;
|
|
140
|
-
path = join(directory, `${id}.md`);
|
|
141
|
-
}
|
|
142
|
-
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
143
|
-
writeFileSync(temporaryPath, content, { encoding: "utf8", mode: 0o600 });
|
|
144
|
-
chmodSync(temporaryPath, 0o600);
|
|
145
|
-
renameSync(temporaryPath, path);
|
|
146
|
-
chmodSync(path, 0o600);
|
|
147
|
-
return parseCloudPromptTemplate(path)!;
|
|
148
|
-
}
|
|
File without changes
|