@akanjs/cli 3.0.0-beta.13 → 3.0.0-beta.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/.build-stamp +1 -1
- package/CodeAgent-d3wvbq8q.js +9 -0
- package/CodeAgentRpcHost-qvwfv0n9.js +7 -0
- package/CodeTui-6c9a2wtk.js +1103 -0
- package/README.md +3 -0
- package/{TunnelShare-2kwqb1j6.js → TunnelShare-r5tc2qk5.js} +2 -2
- package/{agent.command-7357vxd8.js → agent.command-9cg8m87z.js} +6 -6
- package/akanCode.js +100 -0
- package/{application.command-8s8ns95d.js → application.command-x75men32.js} +6 -15
- package/{applicationBuildRunner-4f1wrba0.js → applicationBuildRunner-d3702f1w.js} +2 -2
- package/{applicationReleasePackager-jkjmy5ee.js → applicationReleasePackager-2kdyj3te.js} +1 -1
- package/buildBatch.proc.js +2 -2
- package/{capacitorApp-hqvsrec4.js → capacitorApp-qk975zyz.js} +2 -2
- package/{cloud.command-p5dnhft9.js → cloud.command-a09wggfq.js} +10 -22
- package/cloud.script-qd3hpybf.js +20 -0
- package/code.command-ca7rpmez.js +147 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/{context.command-wsjt98c1.js → context.command-9kbm0527.js} +14 -15
- package/context.runner-wtqpw7mh.js +22 -0
- package/{devTui-myg3pqeg.js → devTui-v19fbnpk.js} +114 -8
- package/{devTuiView-gz2fbf4v.js → devTuiView-pa63jrjq.js} +1 -1
- package/guideline.command-qvrh5pnx.js +48 -0
- package/guidelines/agentRule/agentRule.instruction.md +46 -15
- package/guidelines/conventions/conventions.instruction.md +9 -4
- package/guidelines/moduleCodegen/moduleCodegen.instruction.md +1 -1
- package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +1 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +62 -0
- package/incrementalBuilder.proc.js +1 -1
- package/{index-bz10w9t2.js → index-0qvq9aeb.js} +6 -16
- package/{index-jwjaf9fy.js → index-1p146w4s.js} +44 -44
- package/{index-7f4dsf9v.js → index-1sggq0m8.js} +1 -1
- package/{index-15r9a10e.js → index-3dmebxnk.js} +2 -2
- package/{index-vrwdx0zx.js → index-3hr7cpy1.js} +1 -1
- package/{index-s3fvrydw.js → index-5hy11qaq.js} +9 -9
- package/{index-8pkvrcv1.js → index-658xafm1.js} +3 -3
- package/index-7md2g9vw.js +6 -0
- package/{index-ys7dvdb3.js → index-84b080zh.js} +1 -1
- package/index-8k16atqy.js +82 -0
- package/{index-t3c045et.js → index-91brpnzb.js} +8 -21
- package/{index-em4swemt.js → index-bchkysja.js} +3 -3
- package/{index-j7rwsd23.js → index-bzjnp9ap.js} +22 -80
- package/{index-cnzm1wn5.js → index-chp5gqmm.js} +88 -169
- package/{index-h3g1152j.js → index-d35a8vc0.js} +4 -4
- package/{index-1nwxbr2y.js → index-ea1smknd.js} +2 -2
- package/index-egt4vfgb.js +69 -0
- package/index-erzcytap.js +2434 -0
- package/{index-sh88vtye.js → index-f4gpcp98.js} +1 -1
- package/{index-b3ae16mg.js → index-gca9y01h.js} +1 -1
- package/{index-wmb05v4q.js → index-gm76f0qb.js} +1 -1
- package/{index-649svkyt.js → index-myj01w9r.js} +8 -15
- package/index-sxg87a8f.js +727 -0
- package/{index-h7yw2z9n.js → index-twq9p2sp.js} +8 -8
- package/index-v156f836.js +234 -0
- package/index-v1y3cx0k.js +61 -0
- package/{index-t8gvwcrx.js → index-va2je2qm.js} +2 -2
- package/index-wfwknnje.js +124 -0
- package/index-x7g1qzpt.js +121 -0
- package/index.js +21 -20
- package/{library.command-1f9h2ex6.js → library.command-n89re6cx.js} +3 -3
- package/{localRegistry.command-w6w35j4r.js → localRegistry.command-1mmnegph.js} +9 -9
- package/{module.command-8zkq0q9q.js → module.command-4m82zgfp.js} +7 -10
- package/{package.command-y2rh4np7.js → package.command-9dv0p6zq.js} +3 -3
- package/package.json +9 -5
- package/{page.command-e5h29fyt.js → page.command-q86b0m0z.js} +3 -3
- package/{primitive.command-qm7tybpn.js → primitive.command-kaneasq6.js} +6 -9
- package/prompter-9mn3kp36.js +8 -0
- package/{quality.command-5evdd263.js → quality.command-sgapx315.js} +65 -5
- package/{repair.command-c2amvt74.js → repair.command-efc5gdbq.js} +5 -5
- package/{scalar.command-a1ewkmab.js → scalar.command-e2rpkhqy.js} +6 -9
- package/skills/akan-debug/SKILL.md +42 -0
- package/skills/akan-deps/SKILL.md +50 -0
- package/skills/akan-err/SKILL.md +39 -0
- package/skills/akan-module/SKILL.md +45 -0
- package/skills/akan-scaffold/SKILL.md +76 -0
- package/skills/akan-scalar/SKILL.md +52 -0
- package/skills/akan-service/SKILL.md +34 -0
- package/skills/akan-store/SKILL.md +63 -0
- package/skills/akan-ui/SKILL.md +63 -0
- package/skills/akan-validate/SKILL.md +44 -0
- package/{subspace.command-3w5x13a1.js → subspace.command-005rz1x6.js} +5 -5
- package/{tunnel.command-09n8h4s1.js → tunnel.command-66j9estx.js} +4 -4
- package/{workflow.command-y3fct1rq.js → workflow.command-z1xcm4c7.js} +9 -12
- package/{workspace.command-p6td4qad.js → workspace.command-4ahrhp3k.js} +23 -22
- package/abstractCompactor-g04vqcff.js +0 -102
- package/cloud.script-gxpbhras.js +0 -20
- package/guideline.command-snqzfyt0.js +0 -360
- package/index-5tw8t1ts.js +0 -338
- package/index-j1tajctp.js +0 -229
- package/index-kpnp2e10.js +0 -841
- package/index-meh558jy.js +0 -65
- /package/{index-5nyznra1.js → index-p1j0cyvd.js} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
// pkgs/@akanjs/devkit/prompter.ts
|
|
7
7
|
import fsPromise from "fs/promises";
|
|
8
8
|
import { input, select } from "@inquirer/prompts";
|
|
9
|
-
class
|
|
9
|
+
class Prompter2 {
|
|
10
10
|
static async#getGuidelineRoot() {
|
|
11
11
|
const dirname = getDirname2(import.meta.url);
|
|
12
12
|
const candidates = [`${dirname}/guidelines`, `${dirname}/../cli/guidelines`];
|
|
@@ -19,27 +19,27 @@ class Prompter {
|
|
|
19
19
|
return candidates[0];
|
|
20
20
|
}
|
|
21
21
|
static async selectGuideline() {
|
|
22
|
-
const guideNames = await
|
|
22
|
+
const guideNames = await Prompter2.listGuidelines();
|
|
23
23
|
return await select({
|
|
24
24
|
message: "Select a guideline",
|
|
25
25
|
choices: guideNames.map((name) => ({ name, value: name }))
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
static async listGuidelines() {
|
|
29
|
-
const guidelineRoot = await
|
|
29
|
+
const guidelineRoot = await Prompter2.#getGuidelineRoot();
|
|
30
30
|
return (await fsPromise.readdir(guidelineRoot)).filter((name) => !name.startsWith("_")).sort();
|
|
31
31
|
}
|
|
32
32
|
static async getGuideJson(guideName) {
|
|
33
|
-
const guidelineRoot = await
|
|
33
|
+
const guidelineRoot = await Prompter2.#getGuidelineRoot();
|
|
34
34
|
const filePath = `${guidelineRoot}/${guideName}/${guideName}.generate.json`;
|
|
35
35
|
const guideJson = await fsPromise.readFile(filePath, "utf-8");
|
|
36
36
|
return JSON.parse(guideJson);
|
|
37
37
|
}
|
|
38
38
|
static async getInstruction(guideName) {
|
|
39
|
-
const guideNames = await
|
|
39
|
+
const guideNames = await Prompter2.listGuidelines();
|
|
40
40
|
if (!guideNames.includes(guideName))
|
|
41
41
|
throw new Error(`Unknown guideline "${guideName}". Available: ${guideNames.join(", ")}`);
|
|
42
|
-
const guidelineRoot = await
|
|
42
|
+
const guidelineRoot = await Prompter2.#getGuidelineRoot();
|
|
43
43
|
return await fsPromise.readFile(`${guidelineRoot}/${guideName}/${guideName}.instruction.md`, "utf-8");
|
|
44
44
|
}
|
|
45
45
|
static async getUpdateRequest(guideName) {
|
|
@@ -67,7 +67,7 @@ ${request}
|
|
|
67
67
|
`;
|
|
68
68
|
}
|
|
69
69
|
async getDocumentation(guideName) {
|
|
70
|
-
const guidelineRoot = await
|
|
70
|
+
const guidelineRoot = await Prompter2.#getGuidelineRoot();
|
|
71
71
|
const filePath = `${guidelineRoot}/${guideName}/${guideName}.instruction.md`;
|
|
72
72
|
const document = await fsPromise.readFile(filePath, "utf-8");
|
|
73
73
|
return `\`\`\`markdown
|
|
@@ -77,4 +77,4 @@ ${document}
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
export {
|
|
80
|
+
export { Prompter2 };
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
runner,
|
|
4
|
+
script
|
|
5
|
+
} from "./index-gca9y01h.js";
|
|
6
|
+
import {
|
|
7
|
+
ModuleExecutor
|
|
8
|
+
} from "./index-p1j0cyvd.js";
|
|
9
|
+
import {
|
|
10
|
+
sourceFile,
|
|
11
|
+
moduleSourcePaths,
|
|
12
|
+
generatedFilesForSync,
|
|
13
|
+
createPassedPrimitiveReport,
|
|
14
|
+
bilingualLabelForField,
|
|
15
|
+
bilingualDescriptionForField
|
|
16
|
+
} from "./index-1p146w4s.js";
|
|
17
|
+
import {
|
|
18
|
+
PageScript
|
|
19
|
+
} from "./index-f4gpcp98.js";
|
|
20
|
+
import {
|
|
21
|
+
pluralizeName
|
|
22
|
+
} from "./index-nz8prx9g.js";
|
|
23
|
+
|
|
24
|
+
// pkgs/@akanjs/cli/module/module.script.ts
|
|
25
|
+
import { capitalize as capitalize2 } from "akanjs/common";
|
|
26
|
+
|
|
27
|
+
// pkgs/@akanjs/cli/module/module.runner.ts
|
|
28
|
+
import { capitalize } from "akanjs/common";
|
|
29
|
+
var purposeByModule = {
|
|
30
|
+
budget: "Budget represents planned or actual money allocated inside the app.",
|
|
31
|
+
project: "Project represents a project workspace or business initiative managed by the app.",
|
|
32
|
+
task: "Task represents work items that move through the app workflow."
|
|
33
|
+
};
|
|
34
|
+
var moduleAbstractContent = (moduleName) => {
|
|
35
|
+
const title = capitalize(moduleName);
|
|
36
|
+
const label = bilingualLabelForField(moduleName);
|
|
37
|
+
const purpose = purposeByModule[moduleName] ?? `${title} represents ${label.en.toLowerCase()} records managed by the app.`;
|
|
38
|
+
return `# ${title} Module Abstract
|
|
39
|
+
|
|
40
|
+
## Purpose
|
|
41
|
+
|
|
42
|
+
${purpose}
|
|
43
|
+
|
|
44
|
+
## Domain Rules
|
|
45
|
+
|
|
46
|
+
- Keep ${label.en.toLowerCase()} data consistent with user-facing dictionary labels.
|
|
47
|
+
|
|
48
|
+
## Data Meaning
|
|
49
|
+
|
|
50
|
+
${label.en} (${label.ko}) is the primary business concept for this module.
|
|
51
|
+
|
|
52
|
+
## Workflows
|
|
53
|
+
|
|
54
|
+
No lifecycle workflow yet.
|
|
55
|
+
|
|
56
|
+
## Agent Notes
|
|
57
|
+
|
|
58
|
+
- Read this abstract before changing the module.
|
|
59
|
+
- Update this file when business invariants, workflows, or public behavior change.
|
|
60
|
+
- Do not update this file for formatting-only, import-only, or style-only changes.
|
|
61
|
+
|
|
62
|
+
## Related Modules
|
|
63
|
+
|
|
64
|
+
- None yet.
|
|
65
|
+
`;
|
|
66
|
+
};
|
|
67
|
+
var localModuleFilename = (moduleName, pathKey) => moduleSourcePaths(moduleName)[pathKey].replace(`lib/${moduleName}/`, "");
|
|
68
|
+
|
|
69
|
+
class ModuleRunner extends runner("module") {
|
|
70
|
+
async createService(module) {
|
|
71
|
+
const serviceName = module.name.replace(/^_+/, "");
|
|
72
|
+
await module.applyTemplate({
|
|
73
|
+
basePath: `.`,
|
|
74
|
+
template: "service",
|
|
75
|
+
dict: { model: serviceName, sysName: module.sys.name }
|
|
76
|
+
});
|
|
77
|
+
const [abstractContent, dictionaryContent, serviceContent, signalContent, storeContent] = await Promise.all([
|
|
78
|
+
module.readFile(`${serviceName}.abstract.md`),
|
|
79
|
+
module.readFile(`${serviceName}.dictionary.ts`),
|
|
80
|
+
module.readFile(`${serviceName}.service.ts`),
|
|
81
|
+
module.readFile(`${serviceName}.signal.ts`),
|
|
82
|
+
module.readFile(`${serviceName}.store.ts`)
|
|
83
|
+
]);
|
|
84
|
+
return {
|
|
85
|
+
abstract: { filename: `${serviceName}.abstract.md`, content: abstractContent },
|
|
86
|
+
dictionary: { filename: `${serviceName}.dictionary.ts`, content: dictionaryContent },
|
|
87
|
+
service: { filename: `${serviceName}.service.ts`, content: serviceContent },
|
|
88
|
+
signal: { filename: `${serviceName}.signal.ts`, content: signalContent },
|
|
89
|
+
store: { filename: `${serviceName}.store.ts`, content: storeContent }
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async removeModule(module) {
|
|
93
|
+
await module.sys.removeDir(`lib/${module.name}`);
|
|
94
|
+
}
|
|
95
|
+
async createComponentTemplate(module, type) {
|
|
96
|
+
await module.sys.applyTemplate({
|
|
97
|
+
basePath: `./lib/${module.name}`,
|
|
98
|
+
template: `module/__Model__.${capitalize(type)}.tsx`,
|
|
99
|
+
dict: { model: module.name, sysName: module.sys.name, sysType: module.sys.type }
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
component: {
|
|
103
|
+
filename: `${capitalize(module.name)}.${capitalize(type)}.tsx`,
|
|
104
|
+
content: await module.sys.readFile(`lib/${module.name}/${capitalize(module.name)}.${capitalize(type)}.tsx`)
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async createModuleTemplate(module) {
|
|
109
|
+
const names = pluralizeName(module.name);
|
|
110
|
+
const modelLabel = bilingualLabelForField(module.name);
|
|
111
|
+
const modelDescription = bilingualDescriptionForField(module.name);
|
|
112
|
+
const filenames = {
|
|
113
|
+
abstract: localModuleFilename(module.name, "abstract"),
|
|
114
|
+
constant: localModuleFilename(module.name, "constant"),
|
|
115
|
+
dictionary: localModuleFilename(module.name, "dictionary"),
|
|
116
|
+
service: localModuleFilename(module.name, "service"),
|
|
117
|
+
store: localModuleFilename(module.name, "store"),
|
|
118
|
+
signal: localModuleFilename(module.name, "signal"),
|
|
119
|
+
unit: localModuleFilename(module.name, "unit"),
|
|
120
|
+
view: localModuleFilename(module.name, "view"),
|
|
121
|
+
template: localModuleFilename(module.name, "template"),
|
|
122
|
+
zone: localModuleFilename(module.name, "zone"),
|
|
123
|
+
util: localModuleFilename(module.name, "util")
|
|
124
|
+
};
|
|
125
|
+
await module.applyTemplate({
|
|
126
|
+
basePath: `.`,
|
|
127
|
+
template: "module",
|
|
128
|
+
dict: {
|
|
129
|
+
model: module.name,
|
|
130
|
+
models: names,
|
|
131
|
+
sysName: module.sys.name,
|
|
132
|
+
sysType: module.sys.type,
|
|
133
|
+
modelLabelEn: modelLabel.en,
|
|
134
|
+
modelLabelKo: modelLabel.ko,
|
|
135
|
+
modelDescEn: modelDescription.en,
|
|
136
|
+
modelDescKo: modelDescription.ko
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
await module.writeFile(filenames.abstract, moduleAbstractContent(module.name));
|
|
140
|
+
const [
|
|
141
|
+
abstractContent,
|
|
142
|
+
constantContent,
|
|
143
|
+
dictionaryContent,
|
|
144
|
+
serviceContent,
|
|
145
|
+
storeContent,
|
|
146
|
+
signalContent,
|
|
147
|
+
unitContent,
|
|
148
|
+
viewContent,
|
|
149
|
+
templateContent,
|
|
150
|
+
zoneContent,
|
|
151
|
+
utilContent
|
|
152
|
+
] = await Promise.all([
|
|
153
|
+
module.readFile(filenames.abstract),
|
|
154
|
+
module.readFile(filenames.constant),
|
|
155
|
+
module.readFile(filenames.dictionary),
|
|
156
|
+
module.readFile(filenames.service),
|
|
157
|
+
module.readFile(filenames.store),
|
|
158
|
+
module.readFile(filenames.signal),
|
|
159
|
+
module.readFile(filenames.unit),
|
|
160
|
+
module.readFile(filenames.view),
|
|
161
|
+
module.readFile(filenames.template),
|
|
162
|
+
module.readFile(filenames.zone),
|
|
163
|
+
module.readFile(filenames.util)
|
|
164
|
+
]);
|
|
165
|
+
return {
|
|
166
|
+
abstract: { filename: filenames.abstract, content: abstractContent },
|
|
167
|
+
constant: { filename: filenames.constant, content: constantContent },
|
|
168
|
+
dictionary: { filename: filenames.dictionary, content: dictionaryContent },
|
|
169
|
+
service: { filename: filenames.service, content: serviceContent },
|
|
170
|
+
store: { filename: filenames.store, content: storeContent },
|
|
171
|
+
signal: { filename: filenames.signal, content: signalContent },
|
|
172
|
+
unit: { filename: filenames.unit, content: unitContent },
|
|
173
|
+
view: { filename: filenames.view, content: viewContent },
|
|
174
|
+
template: { filename: filenames.template, content: templateContent },
|
|
175
|
+
zone: { filename: filenames.zone, content: zoneContent },
|
|
176
|
+
util: { filename: filenames.util, content: utilContent }
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// pkgs/@akanjs/cli/module/module.script.ts
|
|
182
|
+
var moduleChangedFiles = (sys, moduleName, files) => Object.values(files).map((file) => sourceFile(sys, `lib/${moduleName}/${file.filename}`, "create", "Module source file was created."));
|
|
183
|
+
|
|
184
|
+
class ModuleScript extends script("module", [ModuleRunner, PageScript]) {
|
|
185
|
+
async createModuleTemplate(sys, name, { page = false } = {}) {
|
|
186
|
+
const mod = ModuleExecutor.from(sys, name);
|
|
187
|
+
const files = await this.moduleRunner.createModuleTemplate(mod);
|
|
188
|
+
if (page && sys.type === "app")
|
|
189
|
+
await this.pageScript.createCrudPage(mod, { app: sys, basePath: null, single: false });
|
|
190
|
+
await sys.scan();
|
|
191
|
+
return createPassedPrimitiveReport({
|
|
192
|
+
command: "create-module",
|
|
193
|
+
changedFiles: moduleChangedFiles(sys, name, files),
|
|
194
|
+
generatedFiles: generatedFilesForSync(sys, "Generated files were refreshed after module creation."),
|
|
195
|
+
target: sys.name
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async removeModule(mod) {
|
|
199
|
+
await this.moduleRunner.removeModule(mod);
|
|
200
|
+
}
|
|
201
|
+
async createService(sys, name) {
|
|
202
|
+
const service = ModuleExecutor.from(sys, `_${name}`);
|
|
203
|
+
const files = await this.moduleRunner.createService(service);
|
|
204
|
+
await sys.scan();
|
|
205
|
+
return createPassedPrimitiveReport({
|
|
206
|
+
command: "create-service",
|
|
207
|
+
changedFiles: moduleChangedFiles(sys, `_${name}`, files),
|
|
208
|
+
generatedFiles: generatedFilesForSync(sys, "Generated files were refreshed after service creation."),
|
|
209
|
+
target: sys.name
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
async createTest(workspace, name) {}
|
|
213
|
+
async createTemplate(mod) {
|
|
214
|
+
return await this.#createComponent(mod, "template");
|
|
215
|
+
}
|
|
216
|
+
async createUnit(mod) {
|
|
217
|
+
return await this.#createComponent(mod, "unit");
|
|
218
|
+
}
|
|
219
|
+
async createView(mod) {
|
|
220
|
+
return await this.#createComponent(mod, "view");
|
|
221
|
+
}
|
|
222
|
+
async#createComponent(mod, type) {
|
|
223
|
+
const { component } = await this.moduleRunner.createComponentTemplate(mod, type);
|
|
224
|
+
return createPassedPrimitiveReport({
|
|
225
|
+
command: `create-${type}`,
|
|
226
|
+
changedFiles: [
|
|
227
|
+
sourceFile(mod.sys, `lib/${mod.name}/${component.filename}`, "create", `${capitalize2(type)} UI source was created.`)
|
|
228
|
+
],
|
|
229
|
+
target: mod.sys.name
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export { ModuleScript };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
runner,
|
|
4
|
+
script
|
|
5
|
+
} from "./index-gca9y01h.js";
|
|
6
|
+
import {
|
|
7
|
+
generatedFilesForSync,
|
|
8
|
+
createPassedPrimitiveReport,
|
|
9
|
+
scalarChangedFiles
|
|
10
|
+
} from "./index-1p146w4s.js";
|
|
11
|
+
import {
|
|
12
|
+
pluralizeName
|
|
13
|
+
} from "./index-nz8prx9g.js";
|
|
14
|
+
|
|
15
|
+
// pkgs/@akanjs/cli/scalar/scalar.runner.ts
|
|
16
|
+
class ScalarRunner extends runner("scalar") {
|
|
17
|
+
async applyScalarTemplate(sys, scalarName) {
|
|
18
|
+
await sys.applyTemplate({
|
|
19
|
+
basePath: "./lib/__scalar",
|
|
20
|
+
template: "__scalar",
|
|
21
|
+
dict: { model: scalarName, models: pluralizeName(scalarName), sysName: sys.name },
|
|
22
|
+
overwrite: false
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
abstract: {
|
|
26
|
+
filename: `${scalarName}.abstract.md`,
|
|
27
|
+
content: await sys.readFile(`lib/__scalar/${scalarName}/${scalarName}.abstract.md`)
|
|
28
|
+
},
|
|
29
|
+
constant: {
|
|
30
|
+
filename: `${scalarName}.constant.ts`,
|
|
31
|
+
content: await sys.readFile(`lib/__scalar/${scalarName}/${scalarName}.constant.ts`)
|
|
32
|
+
},
|
|
33
|
+
dictionary: {
|
|
34
|
+
filename: `${scalarName}.dictionary.ts`,
|
|
35
|
+
content: await sys.readFile(`lib/__scalar/${scalarName}/${scalarName}.dictionary.ts`)
|
|
36
|
+
},
|
|
37
|
+
document: {
|
|
38
|
+
filename: `${scalarName}.document.ts`,
|
|
39
|
+
content: await sys.readFile(`lib/__scalar/${scalarName}/${scalarName}.document.ts`)
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// pkgs/@akanjs/cli/scalar/scalar.script.ts
|
|
46
|
+
class ScalarScript extends script("scalar", [ScalarRunner]) {
|
|
47
|
+
async createScalar(sys, scalarName) {
|
|
48
|
+
const files = await this.scalarRunner.applyScalarTemplate(sys, scalarName);
|
|
49
|
+
return createPassedPrimitiveReport({
|
|
50
|
+
command: "create-scalar",
|
|
51
|
+
changedFiles: scalarChangedFiles(sys, scalarName, files),
|
|
52
|
+
generatedFiles: generatedFilesForSync(sys),
|
|
53
|
+
target: sys.name
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async removeScalar(sys, scalarName) {
|
|
57
|
+
await sys.removeDir(`lib/__scalar/${scalarName}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { ScalarScript };
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-gca9y01h.js";
|
|
6
6
|
import {
|
|
7
7
|
FileSys
|
|
8
8
|
} from "./index-q0y2jq9j.js";
|
|
9
9
|
import {
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-p1j0cyvd.js";
|
|
12
12
|
import {
|
|
13
13
|
TypeScriptDependencyScanner2
|
|
14
14
|
} from "./index-kcxmv48c.js";
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/akanCodeModel.ts
|
|
3
|
+
var akanCodeDefaultModel2 = { provider: "deepseek", id: "deepseek-v4-flash" };
|
|
4
|
+
var catalogueMissesImages = new Set(["deepseek/deepseek-v4-flash"]);
|
|
5
|
+
var correctInputs = (model) => {
|
|
6
|
+
if (!model || model.input.includes("image"))
|
|
7
|
+
return model;
|
|
8
|
+
if (!catalogueMissesImages.has(`${model.provider}/${model.id}`))
|
|
9
|
+
return model;
|
|
10
|
+
return { ...model, input: [...model.input, "image"] };
|
|
11
|
+
};
|
|
12
|
+
var akanCodeModel2 = async (registry, ref) => {
|
|
13
|
+
if (ref) {
|
|
14
|
+
const requested = registry.find(ref.provider, ref.id);
|
|
15
|
+
if (!requested)
|
|
16
|
+
throw new Error(`Unknown model: ${ref.provider}/${ref.id}`);
|
|
17
|
+
if (!registry.hasConfiguredAuth(requested))
|
|
18
|
+
throw new Error(`No API key configured for ${ref.provider}. Set ${ref.provider.toUpperCase()}_API_KEY.`);
|
|
19
|
+
return correctInputs(requested);
|
|
20
|
+
}
|
|
21
|
+
const fallback = registry.find(akanCodeDefaultModel2.provider, akanCodeDefaultModel2.id);
|
|
22
|
+
if (fallback && registry.hasConfiguredAuth(fallback))
|
|
23
|
+
return correctInputs(fallback);
|
|
24
|
+
return correctInputs(registry.getAvailable()[0]);
|
|
25
|
+
};
|
|
26
|
+
var akanCodeModelSupportsImages2 = (model) => !!model?.input.includes("image");
|
|
27
|
+
var akanCodeModelWarnings2 = (model, compactionFloor) => {
|
|
28
|
+
if (!model)
|
|
29
|
+
return [];
|
|
30
|
+
if (model.contextWindow >= compactionFloor)
|
|
31
|
+
return [];
|
|
32
|
+
return [
|
|
33
|
+
`${model.provider}/${model.id} declares a ${model.contextWindow}-token context window, below the ${compactionFloor} the compaction policy needs, so every turn will compact immediately. Check the model entry in ~/.akan/code/models.json.`
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentStreamPrinter.ts
|
|
38
|
+
import { codeAgentEventLabel } from "akanjs/common";
|
|
39
|
+
import chalk from "chalk";
|
|
40
|
+
|
|
41
|
+
class CodeAgentStreamPrinter2 {
|
|
42
|
+
#options;
|
|
43
|
+
#write;
|
|
44
|
+
#streaming = false;
|
|
45
|
+
constructor(options = {}) {
|
|
46
|
+
this.#options = options;
|
|
47
|
+
this.#write = options.write ?? ((text) => process.stdout.write(text));
|
|
48
|
+
}
|
|
49
|
+
print(event) {
|
|
50
|
+
if (this.#options.json)
|
|
51
|
+
return this.#write(`${JSON.stringify(event)}
|
|
52
|
+
`);
|
|
53
|
+
switch (event.type) {
|
|
54
|
+
case "text_delta":
|
|
55
|
+
this.#streaming = true;
|
|
56
|
+
return this.#write(event.text);
|
|
57
|
+
case "thinking_delta":
|
|
58
|
+
if (!this.#options.thinking)
|
|
59
|
+
return;
|
|
60
|
+
this.#streaming = true;
|
|
61
|
+
return this.#write(chalk.dim(event.text));
|
|
62
|
+
case "message":
|
|
63
|
+
return;
|
|
64
|
+
case "tool_start":
|
|
65
|
+
return this.#line(chalk.cyan(`\u2192 ${event.tool.title}`));
|
|
66
|
+
case "tool_progress":
|
|
67
|
+
return;
|
|
68
|
+
case "tool_end":
|
|
69
|
+
return this.#line(CodeAgentStreamPrinter2.#toolEnd(event));
|
|
70
|
+
case "session":
|
|
71
|
+
return this.#line(chalk.dim(codeAgentEventLabel(event)));
|
|
72
|
+
case "turn_end":
|
|
73
|
+
if (event.stopReason === "truncated")
|
|
74
|
+
return this.#line(chalk.yellow(codeAgentEventLabel(event)));
|
|
75
|
+
return;
|
|
76
|
+
case "turn_start":
|
|
77
|
+
case "idle":
|
|
78
|
+
case "queue":
|
|
79
|
+
case "context":
|
|
80
|
+
return;
|
|
81
|
+
case "question":
|
|
82
|
+
return this.#line(chalk.yellow(`? ${event.question.prompt}`));
|
|
83
|
+
case "approval":
|
|
84
|
+
return this.#line(chalk.yellow(`approve? ${event.request.summary}`));
|
|
85
|
+
case "notice":
|
|
86
|
+
return this.#line(CodeAgentStreamPrinter2.#notice(event.level, event.message));
|
|
87
|
+
case "error":
|
|
88
|
+
return this.#line(chalk.red(`error: ${event.message}`));
|
|
89
|
+
default:
|
|
90
|
+
return this.#line(chalk.dim(codeAgentEventLabel(event)));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
finish() {
|
|
94
|
+
if (this.#streaming)
|
|
95
|
+
this.#write(`
|
|
96
|
+
`);
|
|
97
|
+
this.#streaming = false;
|
|
98
|
+
}
|
|
99
|
+
#line(text) {
|
|
100
|
+
if (this.#streaming)
|
|
101
|
+
this.#write(`
|
|
102
|
+
`);
|
|
103
|
+
this.#streaming = false;
|
|
104
|
+
this.#write(`${text}
|
|
105
|
+
`);
|
|
106
|
+
}
|
|
107
|
+
static #toolEnd(event) {
|
|
108
|
+
if (event.outcome === "ok")
|
|
109
|
+
return chalk.green(`\u2713 ${event.tool.title}`);
|
|
110
|
+
if (event.outcome === "blocked")
|
|
111
|
+
return chalk.yellow(`\u29B8 ${event.tool.title} \u2014 ${event.output}`);
|
|
112
|
+
return chalk.red(`\u2717 ${event.tool.title} \u2014 ${event.output.split(`
|
|
113
|
+
`)[0] ?? ""}`);
|
|
114
|
+
}
|
|
115
|
+
static #notice(level, message) {
|
|
116
|
+
if (level === "error")
|
|
117
|
+
return chalk.red(message);
|
|
118
|
+
if (level === "warning")
|
|
119
|
+
return chalk.yellow(message);
|
|
120
|
+
return chalk.dim(message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { akanCodeDefaultModel2, akanCodeModel2, akanCodeModelSupportsImages2, akanCodeModelWarnings2, CodeAgentStreamPrinter2 };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/SubagentPool.ts
|
|
3
|
+
import { codeAgentReadOnlyBuiltins } from "akanjs/common";
|
|
4
|
+
import { Type } from "typebox";
|
|
5
|
+
var maxResultChars = 8000;
|
|
6
|
+
|
|
7
|
+
class SubagentPool2 {
|
|
8
|
+
static kinds = {
|
|
9
|
+
explore: {
|
|
10
|
+
readOnly: true,
|
|
11
|
+
desc: "reads, searches and reports back. It cannot write a file or run a command."
|
|
12
|
+
},
|
|
13
|
+
code: {
|
|
14
|
+
readOnly: false,
|
|
15
|
+
desc: "makes the change itself, with the same tools as this session."
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
static defaultKind = "explore";
|
|
19
|
+
#options;
|
|
20
|
+
#running = 0;
|
|
21
|
+
#spent = 0;
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.#options = options;
|
|
24
|
+
}
|
|
25
|
+
static extensionFor(options) {
|
|
26
|
+
if (!options.parent.tools.subagent)
|
|
27
|
+
return;
|
|
28
|
+
if (options.depth >= options.parent.tools.subagent.maxDepth)
|
|
29
|
+
return;
|
|
30
|
+
const pool = new SubagentPool2(options);
|
|
31
|
+
return { name: "akan-subagent", factory: (pi) => pool.#register(pi) };
|
|
32
|
+
}
|
|
33
|
+
static toolName = "task";
|
|
34
|
+
#register(pi) {
|
|
35
|
+
pi.registerTool({
|
|
36
|
+
name: SubagentPool2.toolName,
|
|
37
|
+
label: "Task",
|
|
38
|
+
description: "Run a focused sub-agent on one self-contained question and get back its answer. Use it for searching and reading that would otherwise fill this conversation \u2014 the sub-agent's own reading does not come back, only its answer. Give it everything it needs: it cannot see this conversation.",
|
|
39
|
+
promptSnippet: "task: run a sub-agent on one self-contained question and get back only its answer",
|
|
40
|
+
parameters: Type.Object({
|
|
41
|
+
description: Type.String({ description: "Three to five words naming the task, for the activity log." }),
|
|
42
|
+
prompt: Type.String({
|
|
43
|
+
description: "The complete instruction. The sub-agent sees nothing of this conversation."
|
|
44
|
+
}),
|
|
45
|
+
type: Type.Optional(Type.Union(Object.entries(SubagentPool2.kinds).map(([kind, spec]) => Type.Literal(kind, { description: spec.desc })), { description: `What the sub-agent may do. Defaults to ${SubagentPool2.defaultKind}.` }))
|
|
46
|
+
}),
|
|
47
|
+
execute: async (_id, params, signal) => {
|
|
48
|
+
const kind = params.type ?? SubagentPool2.defaultKind;
|
|
49
|
+
const refusal = this.#refuse();
|
|
50
|
+
if (refusal)
|
|
51
|
+
return { content: [{ type: "text", text: refusal }], details: undefined, isError: true };
|
|
52
|
+
this.#running += 1;
|
|
53
|
+
this.#options.onNotice?.(`${kind} sub-agent \xB7 ${params.description}`);
|
|
54
|
+
try {
|
|
55
|
+
const text = await this.#run(kind, params.prompt, signal);
|
|
56
|
+
return { content: [{ type: "text", text }], details: undefined };
|
|
57
|
+
} finally {
|
|
58
|
+
this.#running -= 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
#refuse() {
|
|
64
|
+
const budget = this.#options.parent.tools.subagent;
|
|
65
|
+
if (!budget)
|
|
66
|
+
return "Sub-agents are disabled by this profile.";
|
|
67
|
+
if (this.#running >= budget.maxConcurrent)
|
|
68
|
+
return `Too many sub-agents are already running (limit ${budget.maxConcurrent}). Wait for one to finish.`;
|
|
69
|
+
if (this.#spent >= budget.budget)
|
|
70
|
+
return `The sub-agent token budget (${budget.budget}) is spent. Do the rest of this work yourself.`;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
static childOf(parent, kind) {
|
|
74
|
+
const budget = parent.tools.subagent;
|
|
75
|
+
return {
|
|
76
|
+
...parent,
|
|
77
|
+
name: `${parent.name}:${kind}`,
|
|
78
|
+
tools: {
|
|
79
|
+
...parent.tools,
|
|
80
|
+
builtin: SubagentPool2.kinds[kind].readOnly ? parent.tools.builtin.filter((tool) => codeAgentReadOnlyBuiltins.includes(tool)) : parent.tools.builtin,
|
|
81
|
+
subagent: budget ? { ...budget, maxDepth: budget.maxDepth } : false
|
|
82
|
+
},
|
|
83
|
+
session: { store: "memory", crossSession: false },
|
|
84
|
+
ui: { canPrompt: false },
|
|
85
|
+
context: { projectFiles: false, skills: parent.context.skills }
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async#run(kind, prompt, signal) {
|
|
89
|
+
const { CodeAgent } = await import("./CodeAgent-d3wvbq8q.js");
|
|
90
|
+
const budget = this.#options.parent.tools.subagent;
|
|
91
|
+
const child = SubagentPool2.childOf(this.#options.parent, kind);
|
|
92
|
+
const agent = await CodeAgent.create({
|
|
93
|
+
workspace: this.#options.workspace,
|
|
94
|
+
cwd: this.#options.cwd,
|
|
95
|
+
profile: child,
|
|
96
|
+
apps: [],
|
|
97
|
+
depth: this.#options.depth + 1
|
|
98
|
+
});
|
|
99
|
+
const abort = () => void agent.abort();
|
|
100
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
101
|
+
try {
|
|
102
|
+
let answer = "";
|
|
103
|
+
agent.on((event) => {
|
|
104
|
+
if (event.type === "message" && event.role === "assistant")
|
|
105
|
+
answer = event.text;
|
|
106
|
+
});
|
|
107
|
+
await agent.prompt(prompt);
|
|
108
|
+
await agent.waitForIdle();
|
|
109
|
+
this.#spent += agent.tokensUsed;
|
|
110
|
+
const ceiling = budget ? budget.budget : 0;
|
|
111
|
+
this.#options.onNotice?.(`${kind} sub-agent finished, ${agent.tokensUsed} tokens (${this.#spent} of ${ceiling} spent)`);
|
|
112
|
+
return answer.length > maxResultChars ? `${answer.slice(0, maxResultChars)}
|
|
113
|
+
\u2026(truncated)` : answer || "(no answer)";
|
|
114
|
+
} finally {
|
|
115
|
+
signal?.removeEventListener("abort", abort);
|
|
116
|
+
agent.dispose();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export { SubagentPool2 };
|
package/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
getTargetMetas,
|
|
5
5
|
getTargetCommandNames,
|
|
6
6
|
runCommands
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-gca9y01h.js";
|
|
8
8
|
import"./index-q0y2jq9j.js";
|
|
9
|
-
import"./index-
|
|
9
|
+
import"./index-p1j0cyvd.js";
|
|
10
10
|
import"./index-6wwzs1bc.js";
|
|
11
11
|
|
|
12
12
|
// pkgs/@akanjs/cli/commandManifest.ts
|
|
@@ -14,24 +14,25 @@ import path from "path";
|
|
|
14
14
|
|
|
15
15
|
// pkgs/@akanjs/cli/commandModules.ts
|
|
16
16
|
var commandModules = {
|
|
17
|
-
workspace: async () => (await import("./workspace.command-
|
|
18
|
-
agent: async () => (await import("./agent.command-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
workspace: async () => (await import("./workspace.command-4ahrhp3k.js")).WorkspaceCommand,
|
|
18
|
+
agent: async () => (await import("./agent.command-9cg8m87z.js")).AgentCommand,
|
|
19
|
+
code: async () => (await import("./code.command-ca7rpmez.js")).CodeCommand,
|
|
20
|
+
application: async () => (await import("./application.command-x75men32.js")).ApplicationCommand,
|
|
21
|
+
library: async () => (await import("./library.command-n89re6cx.js")).LibraryCommand,
|
|
22
|
+
localRegistry: async () => (await import("./localRegistry.command-1mmnegph.js")).LocalRegistryCommand,
|
|
23
|
+
package: async () => (await import("./package.command-9dv0p6zq.js")).PackageCommand,
|
|
24
|
+
module: async () => (await import("./module.command-4m82zgfp.js")).ModuleCommand,
|
|
25
|
+
page: async () => (await import("./page.command-q86b0m0z.js")).PageCommand,
|
|
26
|
+
context: async () => (await import("./context.command-9kbm0527.js")).ContextCommand,
|
|
27
|
+
cloud: async () => (await import("./cloud.command-a09wggfq.js")).CloudCommand,
|
|
28
|
+
subspace: async () => (await import("./subspace.command-005rz1x6.js")).SubspaceCommand,
|
|
29
|
+
guideline: async () => (await import("./guideline.command-qvrh5pnx.js")).GuidelineCommand,
|
|
30
|
+
scalar: async () => (await import("./scalar.command-e2rpkhqy.js")).ScalarCommand,
|
|
31
|
+
primitive: async () => (await import("./primitive.command-kaneasq6.js")).PrimitiveCommand,
|
|
32
|
+
quality: async () => (await import("./quality.command-sgapx315.js")).QualityCommand,
|
|
33
|
+
repair: async () => (await import("./repair.command-efc5gdbq.js")).RepairCommand,
|
|
34
|
+
workflow: async () => (await import("./workflow.command-z1xcm4c7.js")).WorkflowCommand,
|
|
35
|
+
tunnel: async () => (await import("./tunnel.command-66j9estx.js")).TunnelCommand
|
|
35
36
|
};
|
|
36
37
|
var commandModuleIds = Object.keys(commandModules);
|
|
37
38
|
|