micode 0.9.1 → 0.10.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/README.md +40 -4
- package/dist/index.js +1613 -530
- package/package.json +2 -1
- package/src/agents/brainstormer.ts +1 -1
- package/src/agents/commander.ts +2 -1
- package/src/agents/index.ts +27 -26
- package/src/config-loader.test.ts +53 -2
- package/src/config-loader.ts +77 -17
- package/src/hooks/fetch-tracker.ts +233 -0
- package/src/index.ts +22 -5
- package/src/mindmodel/loader.ts +3 -2
- package/src/tools/mindmodel-lookup.ts +2 -2
- package/src/tools/pty/index.ts +10 -8
- package/src/tools/pty/manager.ts +33 -3
- package/src/tools/pty/pty-loader.ts +123 -0
- package/src/utils/config.ts +25 -0
package/dist/index.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
4
|
+
var __returnValue = (v) => v;
|
|
5
|
+
function __exportSetter(name, newValue) {
|
|
6
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
7
|
+
}
|
|
4
8
|
var __export = (target, all) => {
|
|
5
9
|
for (var name in all)
|
|
6
10
|
__defProp(target, name, {
|
|
7
11
|
get: all[name],
|
|
8
12
|
enumerable: true,
|
|
9
13
|
configurable: true,
|
|
10
|
-
set: (
|
|
14
|
+
set: __exportSetter.bind(all, name)
|
|
11
15
|
});
|
|
12
16
|
};
|
|
13
17
|
var __require = import.meta.require;
|
|
@@ -72,7 +76,7 @@ var require_visit = __commonJS((exports) => {
|
|
|
72
76
|
var BREAK = Symbol("break visit");
|
|
73
77
|
var SKIP = Symbol("skip children");
|
|
74
78
|
var REMOVE = Symbol("remove node");
|
|
75
|
-
function
|
|
79
|
+
function visit2(node, visitor) {
|
|
76
80
|
const visitor_ = initVisitor(visitor);
|
|
77
81
|
if (identity.isDocument(node)) {
|
|
78
82
|
const cd = visit_(null, node.contents, visitor_, Object.freeze([node]));
|
|
@@ -81,9 +85,9 @@ var require_visit = __commonJS((exports) => {
|
|
|
81
85
|
} else
|
|
82
86
|
visit_(null, node, visitor_, Object.freeze([]));
|
|
83
87
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
visit2.BREAK = BREAK;
|
|
89
|
+
visit2.SKIP = SKIP;
|
|
90
|
+
visit2.REMOVE = REMOVE;
|
|
87
91
|
function visit_(key, node, visitor, path) {
|
|
88
92
|
const ctrl = callVisitor(key, node, visitor, path);
|
|
89
93
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
@@ -217,14 +221,14 @@ var require_visit = __commonJS((exports) => {
|
|
|
217
221
|
throw new Error(`Cannot replace node with ${pt} parent`);
|
|
218
222
|
}
|
|
219
223
|
}
|
|
220
|
-
exports.visit =
|
|
224
|
+
exports.visit = visit2;
|
|
221
225
|
exports.visitAsync = visitAsync;
|
|
222
226
|
});
|
|
223
227
|
|
|
224
228
|
// node_modules/yaml/dist/doc/directives.js
|
|
225
229
|
var require_directives = __commonJS((exports) => {
|
|
226
230
|
var identity = require_identity();
|
|
227
|
-
var
|
|
231
|
+
var visit2 = require_visit();
|
|
228
232
|
var escapeChars = {
|
|
229
233
|
"!": "%21",
|
|
230
234
|
",": "%2C",
|
|
@@ -351,7 +355,7 @@ var require_directives = __commonJS((exports) => {
|
|
|
351
355
|
let tagNames;
|
|
352
356
|
if (doc && tagEntries.length > 0 && identity.isNode(doc.contents)) {
|
|
353
357
|
const tags = {};
|
|
354
|
-
|
|
358
|
+
visit2.visit(doc.contents, (_key, node) => {
|
|
355
359
|
if (identity.isNode(node) && node.tag)
|
|
356
360
|
tags[node.tag] = true;
|
|
357
361
|
});
|
|
@@ -376,7 +380,7 @@ var require_directives = __commonJS((exports) => {
|
|
|
376
380
|
// node_modules/yaml/dist/doc/anchors.js
|
|
377
381
|
var require_anchors = __commonJS((exports) => {
|
|
378
382
|
var identity = require_identity();
|
|
379
|
-
var
|
|
383
|
+
var visit2 = require_visit();
|
|
380
384
|
function anchorIsValid(anchor) {
|
|
381
385
|
if (/[\x00-\x19\s,[\]{}]/.test(anchor)) {
|
|
382
386
|
const sa = JSON.stringify(anchor);
|
|
@@ -387,7 +391,7 @@ var require_anchors = __commonJS((exports) => {
|
|
|
387
391
|
}
|
|
388
392
|
function anchorNames(root) {
|
|
389
393
|
const anchors = new Set;
|
|
390
|
-
|
|
394
|
+
visit2.visit(root, {
|
|
391
395
|
Value(_key, node) {
|
|
392
396
|
if (node.anchor)
|
|
393
397
|
anchors.add(node.anchor);
|
|
@@ -549,7 +553,7 @@ var require_Node = __commonJS((exports) => {
|
|
|
549
553
|
// node_modules/yaml/dist/nodes/Alias.js
|
|
550
554
|
var require_Alias = __commonJS((exports) => {
|
|
551
555
|
var anchors = require_anchors();
|
|
552
|
-
var
|
|
556
|
+
var visit2 = require_visit();
|
|
553
557
|
var identity = require_identity();
|
|
554
558
|
var Node = require_Node();
|
|
555
559
|
var toJS = require_toJS();
|
|
@@ -570,7 +574,7 @@ var require_Alias = __commonJS((exports) => {
|
|
|
570
574
|
nodes = ctx.aliasResolveCache;
|
|
571
575
|
} else {
|
|
572
576
|
nodes = [];
|
|
573
|
-
|
|
577
|
+
visit2.visit(doc, {
|
|
574
578
|
Node: (_key, node) => {
|
|
575
579
|
if (identity.isAlias(node) || identity.hasAnchor(node))
|
|
576
580
|
nodes.push(node);
|
|
@@ -2206,14 +2210,14 @@ var require_bool = __commonJS((exports) => {
|
|
|
2206
2210
|
|
|
2207
2211
|
// node_modules/yaml/dist/stringify/stringifyNumber.js
|
|
2208
2212
|
var require_stringifyNumber = __commonJS((exports) => {
|
|
2209
|
-
function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
|
2213
|
+
function stringifyNumber({ format: format2, minFractionDigits, tag, value }) {
|
|
2210
2214
|
if (typeof value === "bigint")
|
|
2211
2215
|
return String(value);
|
|
2212
2216
|
const num = typeof value === "number" ? value : Number(value);
|
|
2213
2217
|
if (!isFinite(num))
|
|
2214
2218
|
return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
|
|
2215
2219
|
let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
|
|
2216
|
-
if (!
|
|
2220
|
+
if (!format2 && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
|
|
2217
2221
|
let i = n.indexOf(".");
|
|
2218
2222
|
if (i < 0) {
|
|
2219
2223
|
i = n.length;
|
|
@@ -5202,15 +5206,15 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5202
5206
|
var BREAK = Symbol("break visit");
|
|
5203
5207
|
var SKIP = Symbol("skip children");
|
|
5204
5208
|
var REMOVE = Symbol("remove item");
|
|
5205
|
-
function
|
|
5209
|
+
function visit2(cst, visitor) {
|
|
5206
5210
|
if ("type" in cst && cst.type === "document")
|
|
5207
5211
|
cst = { start: cst.start, value: cst.value };
|
|
5208
5212
|
_visit(Object.freeze([]), cst, visitor);
|
|
5209
5213
|
}
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
+
visit2.BREAK = BREAK;
|
|
5215
|
+
visit2.SKIP = SKIP;
|
|
5216
|
+
visit2.REMOVE = REMOVE;
|
|
5217
|
+
visit2.itemAtPath = (cst, path) => {
|
|
5214
5218
|
let item = cst;
|
|
5215
5219
|
for (const [field, index] of path) {
|
|
5216
5220
|
const tok = item?.[field];
|
|
@@ -5221,8 +5225,8 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5221
5225
|
}
|
|
5222
5226
|
return item;
|
|
5223
5227
|
};
|
|
5224
|
-
|
|
5225
|
-
const parent =
|
|
5228
|
+
visit2.parentCollection = (cst, path) => {
|
|
5229
|
+
const parent = visit2.itemAtPath(cst, path.slice(0, -1));
|
|
5226
5230
|
const field = path[path.length - 1][0];
|
|
5227
5231
|
const coll = parent?.[field];
|
|
5228
5232
|
if (coll && "items" in coll)
|
|
@@ -5253,7 +5257,7 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5253
5257
|
}
|
|
5254
5258
|
return typeof ctrl === "function" ? ctrl(item, path) : ctrl;
|
|
5255
5259
|
}
|
|
5256
|
-
exports.visit =
|
|
5260
|
+
exports.visit = visit2;
|
|
5257
5261
|
});
|
|
5258
5262
|
|
|
5259
5263
|
// node_modules/yaml/dist/parse/cst.js
|
|
@@ -6867,7 +6871,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
6867
6871
|
}
|
|
6868
6872
|
return doc;
|
|
6869
6873
|
}
|
|
6870
|
-
function
|
|
6874
|
+
function parse4(src, reviver, options) {
|
|
6871
6875
|
let _reviver = undefined;
|
|
6872
6876
|
if (typeof reviver === "function") {
|
|
6873
6877
|
_reviver = reviver;
|
|
@@ -6908,12 +6912,85 @@ var require_public_api = __commonJS((exports) => {
|
|
|
6908
6912
|
return value.toString(options);
|
|
6909
6913
|
return new Document.Document(value, _replacer, options).toString(options);
|
|
6910
6914
|
}
|
|
6911
|
-
exports.parse =
|
|
6915
|
+
exports.parse = parse4;
|
|
6912
6916
|
exports.parseAllDocuments = parseAllDocuments;
|
|
6913
6917
|
exports.parseDocument = parseDocument;
|
|
6914
6918
|
exports.stringify = stringify;
|
|
6915
6919
|
});
|
|
6916
6920
|
|
|
6921
|
+
// src/utils/config.ts
|
|
6922
|
+
var config = {
|
|
6923
|
+
compaction: {
|
|
6924
|
+
threshold: 0.7,
|
|
6925
|
+
cooldownMs: 120000,
|
|
6926
|
+
timeoutMs: 120000
|
|
6927
|
+
},
|
|
6928
|
+
contextWindow: {
|
|
6929
|
+
warningThreshold: 0.7,
|
|
6930
|
+
criticalThreshold: 0.85,
|
|
6931
|
+
warningCooldownMs: 120000
|
|
6932
|
+
},
|
|
6933
|
+
tokens: {
|
|
6934
|
+
charsPerToken: 4,
|
|
6935
|
+
defaultContextLimit: 200000,
|
|
6936
|
+
defaultMaxOutputTokens: 50000,
|
|
6937
|
+
safetyMargin: 0.5,
|
|
6938
|
+
preserveHeaderLines: 3
|
|
6939
|
+
},
|
|
6940
|
+
paths: {
|
|
6941
|
+
ledgerDir: "thoughts/ledgers",
|
|
6942
|
+
ledgerPrefix: "CONTINUITY_",
|
|
6943
|
+
rootContextFiles: ["README.md", "ARCHITECTURE.md", "CODE_STYLE.md"],
|
|
6944
|
+
dirContextFiles: ["README.md"],
|
|
6945
|
+
planPattern: /thoughts\/shared\/plans\/.*\.md$/,
|
|
6946
|
+
ledgerPattern: /thoughts\/ledgers\/CONTINUITY_.*\.md$/,
|
|
6947
|
+
mindmodelDir: ".mindmodel",
|
|
6948
|
+
mindmodelManifest: "manifest.yaml",
|
|
6949
|
+
mindmodelSystem: "system.md"
|
|
6950
|
+
},
|
|
6951
|
+
timeouts: {
|
|
6952
|
+
btcaMs: 120000,
|
|
6953
|
+
toastSuccessMs: 3000,
|
|
6954
|
+
toastWarningMs: 4000,
|
|
6955
|
+
toastErrorMs: 5000
|
|
6956
|
+
},
|
|
6957
|
+
limits: {
|
|
6958
|
+
largeFileBytes: 100 * 1024,
|
|
6959
|
+
maxLinesNoExtract: 200,
|
|
6960
|
+
ptyMaxBufferLines: 50000,
|
|
6961
|
+
ptyDefaultReadLimit: 500,
|
|
6962
|
+
ptyMaxLineLength: 2000,
|
|
6963
|
+
astGrepMaxMatches: 100,
|
|
6964
|
+
contextCacheTtlMs: 30000,
|
|
6965
|
+
contextCacheMaxSize: 100
|
|
6966
|
+
},
|
|
6967
|
+
octto: {
|
|
6968
|
+
answerTimeoutMs: 5 * 60 * 1000,
|
|
6969
|
+
reviewTimeoutMs: 10 * 60 * 1000,
|
|
6970
|
+
maxIterations: 50,
|
|
6971
|
+
maxQuestions: 15,
|
|
6972
|
+
stateDir: "thoughts/brainstorms",
|
|
6973
|
+
bindAddress: "127.0.0.1",
|
|
6974
|
+
allowRemoteBind: false
|
|
6975
|
+
},
|
|
6976
|
+
model: {
|
|
6977
|
+
default: "openai/gpt-5.2-codex"
|
|
6978
|
+
},
|
|
6979
|
+
mindmodel: {
|
|
6980
|
+
overrideLogFile: "overrides.log",
|
|
6981
|
+
reviewMaxRetries: 1,
|
|
6982
|
+
reviewEnabled: true,
|
|
6983
|
+
categoryGroups: ["stack", "architecture", "patterns", "style", "components", "domain", "ops"]
|
|
6984
|
+
},
|
|
6985
|
+
fetch: {
|
|
6986
|
+
warnThreshold: 3,
|
|
6987
|
+
maxCallsPerResource: 5,
|
|
6988
|
+
cacheTtlMs: 300000,
|
|
6989
|
+
cacheMaxEntries: 50
|
|
6990
|
+
}
|
|
6991
|
+
};
|
|
6992
|
+
var DEFAULT_MODEL = config.model.default;
|
|
6993
|
+
|
|
6917
6994
|
// src/agents/artifact-searcher.ts
|
|
6918
6995
|
var artifactSearcherAgent = {
|
|
6919
6996
|
description: "Searches past handoffs, plans, and ledgers for relevant precedent",
|
|
@@ -7262,7 +7339,7 @@ The redesigned artifact system treats artifacts as first\u2011class records stor
|
|
|
7262
7339
|
|
|
7263
7340
|
<phase name="finalizing" trigger="after presenting design">
|
|
7264
7341
|
<action>Write validated design to thoughts/shared/designs/YYYY-MM-DD-{topic}-design.md</action>
|
|
7265
|
-
<action>Commit the design document to git</action>
|
|
7342
|
+
<action>Commit the design document to git (if git add fails because the file is gitignored, skip the commit \u2014 NEVER force-add ignored files)</action>
|
|
7266
7343
|
<action>IMMEDIATELY spawn planner - do NOT ask "Ready for planner?"</action>
|
|
7267
7344
|
<spawn>
|
|
7268
7345
|
Task(
|
|
@@ -7668,6 +7745,7 @@ Not everything needs brainstorm \u2192 plan \u2192 execute.
|
|
|
7668
7745
|
<rule>Commit message format: type(scope): description</rule>
|
|
7669
7746
|
<rule>Types: feat, fix, refactor, docs, test, chore</rule>
|
|
7670
7747
|
<rule>Reference plan file in commit body</rule>
|
|
7748
|
+
<rule>NEVER use git add -f or --force. If a file is gitignored, respect it and skip it.</rule>
|
|
7671
7749
|
</phase>
|
|
7672
7750
|
|
|
7673
7751
|
<phase name="ledger" trigger="context getting full or session ending">
|
|
@@ -7789,7 +7867,7 @@ var primaryAgent = {
|
|
|
7789
7867
|
temperature: 0.2,
|
|
7790
7868
|
thinking: {
|
|
7791
7869
|
type: "enabled",
|
|
7792
|
-
budgetTokens:
|
|
7870
|
+
budgetTokens: 64000
|
|
7793
7871
|
},
|
|
7794
7872
|
maxTokens: 64000,
|
|
7795
7873
|
tools: {
|
|
@@ -10476,221 +10554,1061 @@ Code: \`for (let i = 0; i <= arr.length - 1; i++)\`
|
|
|
10476
10554
|
|
|
10477
10555
|
// src/agents/index.ts
|
|
10478
10556
|
var agents = {
|
|
10479
|
-
[PRIMARY_AGENT_NAME]: { ...primaryAgent, model:
|
|
10480
|
-
brainstormer: { ...brainstormerAgent, model:
|
|
10481
|
-
bootstrapper: { ...bootstrapperAgent, model:
|
|
10482
|
-
"codebase-locator": { ...codebaseLocatorAgent, model:
|
|
10483
|
-
"codebase-analyzer": { ...codebaseAnalyzerAgent, model:
|
|
10484
|
-
"pattern-finder": { ...patternFinderAgent, model:
|
|
10485
|
-
planner: { ...plannerAgent, model:
|
|
10486
|
-
implementer: { ...implementerAgent, model:
|
|
10487
|
-
reviewer: { ...reviewerAgent, model:
|
|
10488
|
-
executor: { ...executorAgent, model:
|
|
10489
|
-
"ledger-creator": { ...ledgerCreatorAgent, model:
|
|
10490
|
-
"artifact-searcher": { ...artifactSearcherAgent, model:
|
|
10491
|
-
"project-initializer": { ...projectInitializerAgent, model:
|
|
10492
|
-
octto: { ...octtoAgent, model:
|
|
10493
|
-
probe: { ...probeAgent, model:
|
|
10494
|
-
"mm-stack-detector": { ...stackDetectorAgent, model:
|
|
10495
|
-
"mm-pattern-discoverer": { ...mindmodelPatternDiscovererAgent, model:
|
|
10496
|
-
"mm-example-extractor": { ...exampleExtractorAgent, model:
|
|
10497
|
-
"mm-orchestrator": { ...mindmodelOrchestratorAgent, model:
|
|
10498
|
-
"mm-dependency-mapper": { ...dependencyMapperAgent, model:
|
|
10499
|
-
"mm-convention-extractor": { ...conventionExtractorAgent, model:
|
|
10500
|
-
"mm-domain-extractor": { ...domainExtractorAgent, model:
|
|
10501
|
-
"mm-code-clusterer": { ...codeClustererAgent, model:
|
|
10502
|
-
"mm-anti-pattern-detector": { ...antiPatternDetectorAgent, model:
|
|
10503
|
-
"mm-constraint-writer": { ...constraintWriterAgent, model:
|
|
10504
|
-
"mm-constraint-reviewer": { ...constraintReviewerAgent, model:
|
|
10557
|
+
[PRIMARY_AGENT_NAME]: { ...primaryAgent, model: DEFAULT_MODEL },
|
|
10558
|
+
brainstormer: { ...brainstormerAgent, model: DEFAULT_MODEL },
|
|
10559
|
+
bootstrapper: { ...bootstrapperAgent, model: DEFAULT_MODEL },
|
|
10560
|
+
"codebase-locator": { ...codebaseLocatorAgent, model: DEFAULT_MODEL },
|
|
10561
|
+
"codebase-analyzer": { ...codebaseAnalyzerAgent, model: DEFAULT_MODEL },
|
|
10562
|
+
"pattern-finder": { ...patternFinderAgent, model: DEFAULT_MODEL },
|
|
10563
|
+
planner: { ...plannerAgent, model: DEFAULT_MODEL },
|
|
10564
|
+
implementer: { ...implementerAgent, model: DEFAULT_MODEL },
|
|
10565
|
+
reviewer: { ...reviewerAgent, model: DEFAULT_MODEL },
|
|
10566
|
+
executor: { ...executorAgent, model: DEFAULT_MODEL },
|
|
10567
|
+
"ledger-creator": { ...ledgerCreatorAgent, model: DEFAULT_MODEL },
|
|
10568
|
+
"artifact-searcher": { ...artifactSearcherAgent, model: DEFAULT_MODEL },
|
|
10569
|
+
"project-initializer": { ...projectInitializerAgent, model: DEFAULT_MODEL },
|
|
10570
|
+
octto: { ...octtoAgent, model: DEFAULT_MODEL },
|
|
10571
|
+
probe: { ...probeAgent, model: DEFAULT_MODEL },
|
|
10572
|
+
"mm-stack-detector": { ...stackDetectorAgent, model: DEFAULT_MODEL },
|
|
10573
|
+
"mm-pattern-discoverer": { ...mindmodelPatternDiscovererAgent, model: DEFAULT_MODEL },
|
|
10574
|
+
"mm-example-extractor": { ...exampleExtractorAgent, model: DEFAULT_MODEL },
|
|
10575
|
+
"mm-orchestrator": { ...mindmodelOrchestratorAgent, model: DEFAULT_MODEL },
|
|
10576
|
+
"mm-dependency-mapper": { ...dependencyMapperAgent, model: DEFAULT_MODEL },
|
|
10577
|
+
"mm-convention-extractor": { ...conventionExtractorAgent, model: DEFAULT_MODEL },
|
|
10578
|
+
"mm-domain-extractor": { ...domainExtractorAgent, model: DEFAULT_MODEL },
|
|
10579
|
+
"mm-code-clusterer": { ...codeClustererAgent, model: DEFAULT_MODEL },
|
|
10580
|
+
"mm-anti-pattern-detector": { ...antiPatternDetectorAgent, model: DEFAULT_MODEL },
|
|
10581
|
+
"mm-constraint-writer": { ...constraintWriterAgent, model: DEFAULT_MODEL },
|
|
10582
|
+
"mm-constraint-reviewer": { ...constraintReviewerAgent, model: DEFAULT_MODEL }
|
|
10505
10583
|
};
|
|
10506
10584
|
|
|
10507
10585
|
// src/config-loader.ts
|
|
10508
|
-
import { readFileSync } from "fs";
|
|
10586
|
+
import { existsSync, readFileSync } from "fs";
|
|
10509
10587
|
import { readFile } from "fs/promises";
|
|
10510
10588
|
import { homedir } from "os";
|
|
10511
10589
|
import { join } from "path";
|
|
10512
|
-
|
|
10513
|
-
|
|
10514
|
-
|
|
10515
|
-
|
|
10516
|
-
|
|
10517
|
-
|
|
10518
|
-
|
|
10519
|
-
|
|
10520
|
-
|
|
10521
|
-
|
|
10522
|
-
|
|
10523
|
-
|
|
10524
|
-
|
|
10525
|
-
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
|
|
10530
|
-
}
|
|
10590
|
+
|
|
10591
|
+
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
10592
|
+
function createScanner(text, ignoreTrivia = false) {
|
|
10593
|
+
const len = text.length;
|
|
10594
|
+
let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
|
|
10595
|
+
function scanHexDigits(count, exact) {
|
|
10596
|
+
let digits = 0;
|
|
10597
|
+
let value2 = 0;
|
|
10598
|
+
while (digits < count || !exact) {
|
|
10599
|
+
let ch = text.charCodeAt(pos);
|
|
10600
|
+
if (ch >= 48 && ch <= 57) {
|
|
10601
|
+
value2 = value2 * 16 + ch - 48;
|
|
10602
|
+
} else if (ch >= 65 && ch <= 70) {
|
|
10603
|
+
value2 = value2 * 16 + ch - 65 + 10;
|
|
10604
|
+
} else if (ch >= 97 && ch <= 102) {
|
|
10605
|
+
value2 = value2 * 16 + ch - 97 + 10;
|
|
10606
|
+
} else {
|
|
10607
|
+
break;
|
|
10531
10608
|
}
|
|
10609
|
+
pos++;
|
|
10610
|
+
digits++;
|
|
10611
|
+
}
|
|
10612
|
+
if (digits < count) {
|
|
10613
|
+
value2 = -1;
|
|
10532
10614
|
}
|
|
10615
|
+
return value2;
|
|
10533
10616
|
}
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
if (parsed.agents && typeof parsed.agents === "object") {
|
|
10550
|
-
const sanitizedAgents = {};
|
|
10551
|
-
for (const [agentName, agentConfig] of Object.entries(parsed.agents)) {
|
|
10552
|
-
if (agentConfig && typeof agentConfig === "object") {
|
|
10553
|
-
const sanitized = {};
|
|
10554
|
-
const config = agentConfig;
|
|
10555
|
-
for (const prop of SAFE_AGENT_PROPERTIES) {
|
|
10556
|
-
if (prop in config) {
|
|
10557
|
-
sanitized[prop] = config[prop];
|
|
10558
|
-
}
|
|
10559
|
-
}
|
|
10560
|
-
sanitizedAgents[agentName] = sanitized;
|
|
10561
|
-
}
|
|
10617
|
+
function setPosition(newPosition) {
|
|
10618
|
+
pos = newPosition;
|
|
10619
|
+
value = "";
|
|
10620
|
+
tokenOffset = 0;
|
|
10621
|
+
token = 16;
|
|
10622
|
+
scanError = 0;
|
|
10623
|
+
}
|
|
10624
|
+
function scanNumber() {
|
|
10625
|
+
let start = pos;
|
|
10626
|
+
if (text.charCodeAt(pos) === 48) {
|
|
10627
|
+
pos++;
|
|
10628
|
+
} else {
|
|
10629
|
+
pos++;
|
|
10630
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
10631
|
+
pos++;
|
|
10562
10632
|
}
|
|
10563
|
-
result.agents = sanitizedAgents;
|
|
10564
|
-
}
|
|
10565
|
-
if (parsed.features && typeof parsed.features === "object") {
|
|
10566
|
-
const features = parsed.features;
|
|
10567
|
-
result.features = {
|
|
10568
|
-
mindmodelInjection: features.mindmodelInjection === true
|
|
10569
|
-
};
|
|
10570
10633
|
}
|
|
10571
|
-
if (
|
|
10572
|
-
|
|
10573
|
-
if (
|
|
10574
|
-
|
|
10634
|
+
if (pos < text.length && text.charCodeAt(pos) === 46) {
|
|
10635
|
+
pos++;
|
|
10636
|
+
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
10637
|
+
pos++;
|
|
10638
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
10639
|
+
pos++;
|
|
10640
|
+
}
|
|
10641
|
+
} else {
|
|
10642
|
+
scanError = 3;
|
|
10643
|
+
return text.substring(start, pos);
|
|
10575
10644
|
}
|
|
10576
10645
|
}
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10646
|
+
let end = pos;
|
|
10647
|
+
if (pos < text.length && (text.charCodeAt(pos) === 69 || text.charCodeAt(pos) === 101)) {
|
|
10648
|
+
pos++;
|
|
10649
|
+
if (pos < text.length && text.charCodeAt(pos) === 43 || text.charCodeAt(pos) === 45) {
|
|
10650
|
+
pos++;
|
|
10651
|
+
}
|
|
10652
|
+
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
10653
|
+
pos++;
|
|
10654
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
10655
|
+
pos++;
|
|
10586
10656
|
}
|
|
10657
|
+
end = pos;
|
|
10658
|
+
} else {
|
|
10659
|
+
scanError = 3;
|
|
10587
10660
|
}
|
|
10588
|
-
result.fragments = sanitizedFragments;
|
|
10589
10661
|
}
|
|
10590
|
-
return
|
|
10591
|
-
} catch {
|
|
10592
|
-
return null;
|
|
10662
|
+
return text.substring(start, end);
|
|
10593
10663
|
}
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10664
|
+
function scanString() {
|
|
10665
|
+
let result = "", start = pos;
|
|
10666
|
+
while (true) {
|
|
10667
|
+
if (pos >= len) {
|
|
10668
|
+
result += text.substring(start, pos);
|
|
10669
|
+
scanError = 2;
|
|
10670
|
+
break;
|
|
10671
|
+
}
|
|
10672
|
+
const ch = text.charCodeAt(pos);
|
|
10673
|
+
if (ch === 34) {
|
|
10674
|
+
result += text.substring(start, pos);
|
|
10675
|
+
pos++;
|
|
10676
|
+
break;
|
|
10677
|
+
}
|
|
10678
|
+
if (ch === 92) {
|
|
10679
|
+
result += text.substring(start, pos);
|
|
10680
|
+
pos++;
|
|
10681
|
+
if (pos >= len) {
|
|
10682
|
+
scanError = 2;
|
|
10683
|
+
break;
|
|
10684
|
+
}
|
|
10685
|
+
const ch2 = text.charCodeAt(pos++);
|
|
10686
|
+
switch (ch2) {
|
|
10687
|
+
case 34:
|
|
10688
|
+
result += '"';
|
|
10689
|
+
break;
|
|
10690
|
+
case 92:
|
|
10691
|
+
result += "\\";
|
|
10692
|
+
break;
|
|
10693
|
+
case 47:
|
|
10694
|
+
result += "/";
|
|
10695
|
+
break;
|
|
10696
|
+
case 98:
|
|
10697
|
+
result += "\b";
|
|
10698
|
+
break;
|
|
10699
|
+
case 102:
|
|
10700
|
+
result += "\f";
|
|
10701
|
+
break;
|
|
10702
|
+
case 110:
|
|
10703
|
+
result += `
|
|
10704
|
+
`;
|
|
10705
|
+
break;
|
|
10706
|
+
case 114:
|
|
10707
|
+
result += "\r";
|
|
10708
|
+
break;
|
|
10709
|
+
case 116:
|
|
10710
|
+
result += "\t";
|
|
10711
|
+
break;
|
|
10712
|
+
case 117:
|
|
10713
|
+
const ch3 = scanHexDigits(4, true);
|
|
10714
|
+
if (ch3 >= 0) {
|
|
10715
|
+
result += String.fromCharCode(ch3);
|
|
10716
|
+
} else {
|
|
10717
|
+
scanError = 4;
|
|
10609
10718
|
}
|
|
10610
|
-
|
|
10719
|
+
break;
|
|
10720
|
+
default:
|
|
10721
|
+
scanError = 5;
|
|
10611
10722
|
}
|
|
10723
|
+
start = pos;
|
|
10724
|
+
continue;
|
|
10612
10725
|
}
|
|
10613
|
-
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
const models = availableModels ?? loadAvailableModels();
|
|
10619
|
-
const shouldValidateModels = models.size > 0;
|
|
10620
|
-
const opencodeDefaultModel = defaultModel ?? loadDefaultModel();
|
|
10621
|
-
const isValidModel = (model) => {
|
|
10622
|
-
if (BUILTIN_MODELS.has(model))
|
|
10623
|
-
return true;
|
|
10624
|
-
if (!shouldValidateModels)
|
|
10625
|
-
return true;
|
|
10626
|
-
return models.has(model);
|
|
10627
|
-
};
|
|
10628
|
-
const merged = {};
|
|
10629
|
-
for (const [name, agentConfig] of Object.entries(pluginAgents)) {
|
|
10630
|
-
const userOverride = userConfig?.agents?.[name];
|
|
10631
|
-
let finalConfig = { ...agentConfig };
|
|
10632
|
-
if (opencodeDefaultModel && isValidModel(opencodeDefaultModel)) {
|
|
10633
|
-
finalConfig = { ...finalConfig, model: opencodeDefaultModel };
|
|
10634
|
-
}
|
|
10635
|
-
if (userOverride) {
|
|
10636
|
-
if (userOverride.model) {
|
|
10637
|
-
if (isValidModel(userOverride.model)) {
|
|
10638
|
-
finalConfig = { ...finalConfig, ...userOverride };
|
|
10726
|
+
if (ch >= 0 && ch <= 31) {
|
|
10727
|
+
if (isLineBreak(ch)) {
|
|
10728
|
+
result += text.substring(start, pos);
|
|
10729
|
+
scanError = 2;
|
|
10730
|
+
break;
|
|
10639
10731
|
} else {
|
|
10640
|
-
|
|
10641
|
-
console.warn(`[micode] Model "${userOverride.model}" for agent "${name}" is not available. Using ${fallbackModel}.`);
|
|
10642
|
-
const { model: _ignored, ...safeOverrides } = userOverride;
|
|
10643
|
-
finalConfig = { ...finalConfig, ...safeOverrides };
|
|
10732
|
+
scanError = 6;
|
|
10644
10733
|
}
|
|
10645
|
-
} else {
|
|
10646
|
-
finalConfig = { ...finalConfig, ...userOverride };
|
|
10647
10734
|
}
|
|
10735
|
+
pos++;
|
|
10648
10736
|
}
|
|
10649
|
-
|
|
10737
|
+
return result;
|
|
10650
10738
|
}
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10739
|
+
function scanNext() {
|
|
10740
|
+
value = "";
|
|
10741
|
+
scanError = 0;
|
|
10742
|
+
tokenOffset = pos;
|
|
10743
|
+
lineStartOffset = lineNumber;
|
|
10744
|
+
prevTokenLineStartOffset = tokenLineStartOffset;
|
|
10745
|
+
if (pos >= len) {
|
|
10746
|
+
tokenOffset = len;
|
|
10747
|
+
return token = 17;
|
|
10748
|
+
}
|
|
10749
|
+
let code = text.charCodeAt(pos);
|
|
10750
|
+
if (isWhiteSpace(code)) {
|
|
10751
|
+
do {
|
|
10752
|
+
pos++;
|
|
10753
|
+
value += String.fromCharCode(code);
|
|
10754
|
+
code = text.charCodeAt(pos);
|
|
10755
|
+
} while (isWhiteSpace(code));
|
|
10756
|
+
return token = 15;
|
|
10757
|
+
}
|
|
10758
|
+
if (isLineBreak(code)) {
|
|
10759
|
+
pos++;
|
|
10760
|
+
value += String.fromCharCode(code);
|
|
10761
|
+
if (code === 13 && text.charCodeAt(pos) === 10) {
|
|
10762
|
+
pos++;
|
|
10763
|
+
value += `
|
|
10764
|
+
`;
|
|
10765
|
+
}
|
|
10766
|
+
lineNumber++;
|
|
10767
|
+
tokenLineStartOffset = pos;
|
|
10768
|
+
return token = 14;
|
|
10769
|
+
}
|
|
10770
|
+
switch (code) {
|
|
10771
|
+
case 123:
|
|
10772
|
+
pos++;
|
|
10773
|
+
return token = 1;
|
|
10774
|
+
case 125:
|
|
10775
|
+
pos++;
|
|
10776
|
+
return token = 2;
|
|
10777
|
+
case 91:
|
|
10778
|
+
pos++;
|
|
10779
|
+
return token = 3;
|
|
10780
|
+
case 93:
|
|
10781
|
+
pos++;
|
|
10782
|
+
return token = 4;
|
|
10783
|
+
case 58:
|
|
10784
|
+
pos++;
|
|
10785
|
+
return token = 6;
|
|
10786
|
+
case 44:
|
|
10787
|
+
pos++;
|
|
10788
|
+
return token = 5;
|
|
10789
|
+
case 34:
|
|
10790
|
+
pos++;
|
|
10791
|
+
value = scanString();
|
|
10792
|
+
return token = 10;
|
|
10793
|
+
case 47:
|
|
10794
|
+
const start = pos - 1;
|
|
10795
|
+
if (text.charCodeAt(pos + 1) === 47) {
|
|
10796
|
+
pos += 2;
|
|
10797
|
+
while (pos < len) {
|
|
10798
|
+
if (isLineBreak(text.charCodeAt(pos))) {
|
|
10799
|
+
break;
|
|
10800
|
+
}
|
|
10801
|
+
pos++;
|
|
10802
|
+
}
|
|
10803
|
+
value = text.substring(start, pos);
|
|
10804
|
+
return token = 12;
|
|
10805
|
+
}
|
|
10806
|
+
if (text.charCodeAt(pos + 1) === 42) {
|
|
10807
|
+
pos += 2;
|
|
10808
|
+
const safeLength = len - 1;
|
|
10809
|
+
let commentClosed = false;
|
|
10810
|
+
while (pos < safeLength) {
|
|
10811
|
+
const ch = text.charCodeAt(pos);
|
|
10812
|
+
if (ch === 42 && text.charCodeAt(pos + 1) === 47) {
|
|
10813
|
+
pos += 2;
|
|
10814
|
+
commentClosed = true;
|
|
10815
|
+
break;
|
|
10816
|
+
}
|
|
10817
|
+
pos++;
|
|
10818
|
+
if (isLineBreak(ch)) {
|
|
10819
|
+
if (ch === 13 && text.charCodeAt(pos) === 10) {
|
|
10820
|
+
pos++;
|
|
10821
|
+
}
|
|
10822
|
+
lineNumber++;
|
|
10823
|
+
tokenLineStartOffset = pos;
|
|
10824
|
+
}
|
|
10825
|
+
}
|
|
10826
|
+
if (!commentClosed) {
|
|
10827
|
+
pos++;
|
|
10828
|
+
scanError = 1;
|
|
10829
|
+
}
|
|
10830
|
+
value = text.substring(start, pos);
|
|
10831
|
+
return token = 13;
|
|
10832
|
+
}
|
|
10833
|
+
value += String.fromCharCode(code);
|
|
10834
|
+
pos++;
|
|
10835
|
+
return token = 16;
|
|
10836
|
+
case 45:
|
|
10837
|
+
value += String.fromCharCode(code);
|
|
10838
|
+
pos++;
|
|
10839
|
+
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
|
10840
|
+
return token = 16;
|
|
10841
|
+
}
|
|
10842
|
+
case 48:
|
|
10843
|
+
case 49:
|
|
10844
|
+
case 50:
|
|
10845
|
+
case 51:
|
|
10846
|
+
case 52:
|
|
10847
|
+
case 53:
|
|
10848
|
+
case 54:
|
|
10849
|
+
case 55:
|
|
10850
|
+
case 56:
|
|
10851
|
+
case 57:
|
|
10852
|
+
value += scanNumber();
|
|
10853
|
+
return token = 11;
|
|
10854
|
+
default:
|
|
10855
|
+
while (pos < len && isUnknownContentCharacter(code)) {
|
|
10856
|
+
pos++;
|
|
10857
|
+
code = text.charCodeAt(pos);
|
|
10858
|
+
}
|
|
10859
|
+
if (tokenOffset !== pos) {
|
|
10860
|
+
value = text.substring(tokenOffset, pos);
|
|
10861
|
+
switch (value) {
|
|
10862
|
+
case "true":
|
|
10863
|
+
return token = 8;
|
|
10864
|
+
case "false":
|
|
10865
|
+
return token = 9;
|
|
10866
|
+
case "null":
|
|
10867
|
+
return token = 7;
|
|
10868
|
+
}
|
|
10869
|
+
return token = 16;
|
|
10870
|
+
}
|
|
10871
|
+
value += String.fromCharCode(code);
|
|
10872
|
+
pos++;
|
|
10873
|
+
return token = 16;
|
|
10874
|
+
}
|
|
10670
10875
|
}
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
mkdirSync(dir, { recursive: true });
|
|
10876
|
+
function isUnknownContentCharacter(code) {
|
|
10877
|
+
if (isWhiteSpace(code) || isLineBreak(code)) {
|
|
10878
|
+
return false;
|
|
10675
10879
|
}
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10880
|
+
switch (code) {
|
|
10881
|
+
case 125:
|
|
10882
|
+
case 93:
|
|
10883
|
+
case 123:
|
|
10884
|
+
case 91:
|
|
10885
|
+
case 34:
|
|
10886
|
+
case 58:
|
|
10887
|
+
case 44:
|
|
10888
|
+
case 47:
|
|
10889
|
+
return false;
|
|
10683
10890
|
}
|
|
10684
|
-
|
|
10891
|
+
return true;
|
|
10685
10892
|
}
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10893
|
+
function scanNextNonTrivia() {
|
|
10894
|
+
let result;
|
|
10895
|
+
do {
|
|
10896
|
+
result = scanNext();
|
|
10897
|
+
} while (result >= 12 && result <= 15);
|
|
10898
|
+
return result;
|
|
10899
|
+
}
|
|
10900
|
+
return {
|
|
10901
|
+
setPosition,
|
|
10902
|
+
getPosition: () => pos,
|
|
10903
|
+
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
|
10904
|
+
getToken: () => token,
|
|
10905
|
+
getTokenValue: () => value,
|
|
10906
|
+
getTokenOffset: () => tokenOffset,
|
|
10907
|
+
getTokenLength: () => pos - tokenOffset,
|
|
10908
|
+
getTokenStartLine: () => lineStartOffset,
|
|
10909
|
+
getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
|
|
10910
|
+
getTokenError: () => scanError
|
|
10911
|
+
};
|
|
10912
|
+
}
|
|
10913
|
+
function isWhiteSpace(ch) {
|
|
10914
|
+
return ch === 32 || ch === 9;
|
|
10915
|
+
}
|
|
10916
|
+
function isLineBreak(ch) {
|
|
10917
|
+
return ch === 10 || ch === 13;
|
|
10918
|
+
}
|
|
10919
|
+
function isDigit(ch) {
|
|
10920
|
+
return ch >= 48 && ch <= 57;
|
|
10921
|
+
}
|
|
10922
|
+
var CharacterCodes;
|
|
10923
|
+
(function(CharacterCodes2) {
|
|
10924
|
+
CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
|
|
10925
|
+
CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
|
|
10926
|
+
CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
|
|
10927
|
+
CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
|
|
10928
|
+
CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
|
|
10929
|
+
CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
|
|
10930
|
+
CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
|
|
10931
|
+
CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
|
|
10932
|
+
CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
|
|
10933
|
+
CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
|
|
10934
|
+
CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
|
|
10935
|
+
CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
|
|
10936
|
+
CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
|
|
10937
|
+
CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
|
|
10938
|
+
CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
|
|
10939
|
+
CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
|
|
10940
|
+
CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
|
|
10941
|
+
CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
|
|
10942
|
+
CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
|
|
10943
|
+
CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
|
|
10944
|
+
CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
|
|
10945
|
+
CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
|
|
10946
|
+
CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
|
|
10947
|
+
CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
|
|
10948
|
+
CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
|
|
10949
|
+
CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
|
|
10950
|
+
CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
|
|
10951
|
+
CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
|
|
10952
|
+
CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
|
|
10953
|
+
CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
|
|
10954
|
+
CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
|
|
10955
|
+
CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
|
|
10956
|
+
CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
|
|
10957
|
+
CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
|
|
10958
|
+
CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
|
|
10959
|
+
CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
|
|
10960
|
+
CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
|
|
10961
|
+
CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
|
|
10962
|
+
CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
|
|
10963
|
+
CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
|
|
10964
|
+
CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
|
|
10965
|
+
CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
|
|
10966
|
+
CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
|
|
10967
|
+
CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
|
|
10968
|
+
CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
|
|
10969
|
+
CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
|
|
10970
|
+
CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
|
|
10971
|
+
CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
|
|
10972
|
+
CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
|
|
10973
|
+
CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
|
|
10974
|
+
CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
|
|
10975
|
+
CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
|
|
10976
|
+
CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
|
|
10977
|
+
CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
|
|
10978
|
+
CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
|
|
10979
|
+
CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
|
|
10980
|
+
CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
|
|
10981
|
+
CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
|
|
10982
|
+
CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
|
|
10983
|
+
CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
|
|
10984
|
+
CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
|
|
10985
|
+
CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
|
|
10986
|
+
CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
|
|
10987
|
+
CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
|
|
10988
|
+
CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
|
|
10989
|
+
CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
|
|
10990
|
+
CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
|
|
10991
|
+
CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
|
|
10992
|
+
CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
|
|
10993
|
+
CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
|
|
10994
|
+
CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
|
|
10995
|
+
CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
|
|
10996
|
+
CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
|
|
10997
|
+
CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
|
|
10998
|
+
CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
|
|
10999
|
+
CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
|
|
11000
|
+
CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
|
|
11001
|
+
CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
|
|
11002
|
+
CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
|
|
11003
|
+
CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
|
|
11004
|
+
})(CharacterCodes || (CharacterCodes = {}));
|
|
11005
|
+
|
|
11006
|
+
// node_modules/jsonc-parser/lib/esm/impl/string-intern.js
|
|
11007
|
+
var cachedSpaces = new Array(20).fill(0).map((_, index) => {
|
|
11008
|
+
return " ".repeat(index);
|
|
11009
|
+
});
|
|
11010
|
+
var maxCachedValues = 200;
|
|
11011
|
+
var cachedBreakLinesWithSpaces = {
|
|
11012
|
+
" ": {
|
|
11013
|
+
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
11014
|
+
return `
|
|
11015
|
+
` + " ".repeat(index);
|
|
11016
|
+
}),
|
|
11017
|
+
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
11018
|
+
return "\r" + " ".repeat(index);
|
|
11019
|
+
}),
|
|
11020
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
11021
|
+
return `\r
|
|
11022
|
+
` + " ".repeat(index);
|
|
11023
|
+
})
|
|
11024
|
+
},
|
|
11025
|
+
"\t": {
|
|
11026
|
+
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
11027
|
+
return `
|
|
11028
|
+
` + "\t".repeat(index);
|
|
11029
|
+
}),
|
|
11030
|
+
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
11031
|
+
return "\r" + "\t".repeat(index);
|
|
11032
|
+
}),
|
|
11033
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
11034
|
+
return `\r
|
|
11035
|
+
` + "\t".repeat(index);
|
|
11036
|
+
})
|
|
11037
|
+
}
|
|
11038
|
+
};
|
|
11039
|
+
|
|
11040
|
+
// node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
11041
|
+
var ParseOptions;
|
|
11042
|
+
(function(ParseOptions2) {
|
|
11043
|
+
ParseOptions2.DEFAULT = {
|
|
11044
|
+
allowTrailingComma: false
|
|
11045
|
+
};
|
|
11046
|
+
})(ParseOptions || (ParseOptions = {}));
|
|
11047
|
+
function parse(text, errors = [], options = ParseOptions.DEFAULT) {
|
|
11048
|
+
let currentProperty = null;
|
|
11049
|
+
let currentParent = [];
|
|
11050
|
+
const previousParents = [];
|
|
11051
|
+
function onValue(value) {
|
|
11052
|
+
if (Array.isArray(currentParent)) {
|
|
11053
|
+
currentParent.push(value);
|
|
11054
|
+
} else if (currentProperty !== null) {
|
|
11055
|
+
currentParent[currentProperty] = value;
|
|
11056
|
+
}
|
|
11057
|
+
}
|
|
11058
|
+
const visitor = {
|
|
11059
|
+
onObjectBegin: () => {
|
|
11060
|
+
const object = {};
|
|
11061
|
+
onValue(object);
|
|
11062
|
+
previousParents.push(currentParent);
|
|
11063
|
+
currentParent = object;
|
|
11064
|
+
currentProperty = null;
|
|
11065
|
+
},
|
|
11066
|
+
onObjectProperty: (name) => {
|
|
11067
|
+
currentProperty = name;
|
|
11068
|
+
},
|
|
11069
|
+
onObjectEnd: () => {
|
|
11070
|
+
currentParent = previousParents.pop();
|
|
11071
|
+
},
|
|
11072
|
+
onArrayBegin: () => {
|
|
11073
|
+
const array = [];
|
|
11074
|
+
onValue(array);
|
|
11075
|
+
previousParents.push(currentParent);
|
|
11076
|
+
currentParent = array;
|
|
11077
|
+
currentProperty = null;
|
|
11078
|
+
},
|
|
11079
|
+
onArrayEnd: () => {
|
|
11080
|
+
currentParent = previousParents.pop();
|
|
11081
|
+
},
|
|
11082
|
+
onLiteralValue: onValue,
|
|
11083
|
+
onError: (error, offset, length) => {
|
|
11084
|
+
errors.push({ error, offset, length });
|
|
11085
|
+
}
|
|
11086
|
+
};
|
|
11087
|
+
visit(text, visitor, options);
|
|
11088
|
+
return currentParent[0];
|
|
11089
|
+
}
|
|
11090
|
+
function visit(text, visitor, options = ParseOptions.DEFAULT) {
|
|
11091
|
+
const _scanner = createScanner(text, false);
|
|
11092
|
+
const _jsonPath = [];
|
|
11093
|
+
let suppressedCallbacks = 0;
|
|
11094
|
+
function toNoArgVisit(visitFunction) {
|
|
11095
|
+
return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
|
|
11096
|
+
}
|
|
11097
|
+
function toOneArgVisit(visitFunction) {
|
|
11098
|
+
return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;
|
|
11099
|
+
}
|
|
11100
|
+
function toOneArgVisitWithPath(visitFunction) {
|
|
11101
|
+
return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;
|
|
11102
|
+
}
|
|
11103
|
+
function toBeginVisit(visitFunction) {
|
|
11104
|
+
return visitFunction ? () => {
|
|
11105
|
+
if (suppressedCallbacks > 0) {
|
|
11106
|
+
suppressedCallbacks++;
|
|
11107
|
+
} else {
|
|
11108
|
+
let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());
|
|
11109
|
+
if (cbReturn === false) {
|
|
11110
|
+
suppressedCallbacks = 1;
|
|
11111
|
+
}
|
|
11112
|
+
}
|
|
11113
|
+
} : () => true;
|
|
11114
|
+
}
|
|
11115
|
+
function toEndVisit(visitFunction) {
|
|
11116
|
+
return visitFunction ? () => {
|
|
11117
|
+
if (suppressedCallbacks > 0) {
|
|
11118
|
+
suppressedCallbacks--;
|
|
11119
|
+
}
|
|
11120
|
+
if (suppressedCallbacks === 0) {
|
|
11121
|
+
visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());
|
|
11122
|
+
}
|
|
11123
|
+
} : () => true;
|
|
11124
|
+
}
|
|
11125
|
+
const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);
|
|
11126
|
+
const disallowComments = options && options.disallowComments;
|
|
11127
|
+
const allowTrailingComma = options && options.allowTrailingComma;
|
|
11128
|
+
function scanNext() {
|
|
11129
|
+
while (true) {
|
|
11130
|
+
const token = _scanner.scan();
|
|
11131
|
+
switch (_scanner.getTokenError()) {
|
|
11132
|
+
case 4:
|
|
11133
|
+
handleError(14);
|
|
11134
|
+
break;
|
|
11135
|
+
case 5:
|
|
11136
|
+
handleError(15);
|
|
11137
|
+
break;
|
|
11138
|
+
case 3:
|
|
11139
|
+
handleError(13);
|
|
11140
|
+
break;
|
|
11141
|
+
case 1:
|
|
11142
|
+
if (!disallowComments) {
|
|
11143
|
+
handleError(11);
|
|
11144
|
+
}
|
|
11145
|
+
break;
|
|
11146
|
+
case 2:
|
|
11147
|
+
handleError(12);
|
|
11148
|
+
break;
|
|
11149
|
+
case 6:
|
|
11150
|
+
handleError(16);
|
|
11151
|
+
break;
|
|
11152
|
+
}
|
|
11153
|
+
switch (token) {
|
|
11154
|
+
case 12:
|
|
11155
|
+
case 13:
|
|
11156
|
+
if (disallowComments) {
|
|
11157
|
+
handleError(10);
|
|
11158
|
+
} else {
|
|
11159
|
+
onComment();
|
|
11160
|
+
}
|
|
11161
|
+
break;
|
|
11162
|
+
case 16:
|
|
11163
|
+
handleError(1);
|
|
11164
|
+
break;
|
|
11165
|
+
case 15:
|
|
11166
|
+
case 14:
|
|
11167
|
+
break;
|
|
11168
|
+
default:
|
|
11169
|
+
return token;
|
|
11170
|
+
}
|
|
11171
|
+
}
|
|
11172
|
+
}
|
|
11173
|
+
function handleError(error, skipUntilAfter = [], skipUntil = []) {
|
|
11174
|
+
onError(error);
|
|
11175
|
+
if (skipUntilAfter.length + skipUntil.length > 0) {
|
|
11176
|
+
let token = _scanner.getToken();
|
|
11177
|
+
while (token !== 17) {
|
|
11178
|
+
if (skipUntilAfter.indexOf(token) !== -1) {
|
|
11179
|
+
scanNext();
|
|
11180
|
+
break;
|
|
11181
|
+
} else if (skipUntil.indexOf(token) !== -1) {
|
|
11182
|
+
break;
|
|
11183
|
+
}
|
|
11184
|
+
token = scanNext();
|
|
11185
|
+
}
|
|
11186
|
+
}
|
|
11187
|
+
}
|
|
11188
|
+
function parseString(isValue) {
|
|
11189
|
+
const value = _scanner.getTokenValue();
|
|
11190
|
+
if (isValue) {
|
|
11191
|
+
onLiteralValue(value);
|
|
11192
|
+
} else {
|
|
11193
|
+
onObjectProperty(value);
|
|
11194
|
+
_jsonPath.push(value);
|
|
11195
|
+
}
|
|
11196
|
+
scanNext();
|
|
11197
|
+
return true;
|
|
11198
|
+
}
|
|
11199
|
+
function parseLiteral() {
|
|
11200
|
+
switch (_scanner.getToken()) {
|
|
11201
|
+
case 11:
|
|
11202
|
+
const tokenValue = _scanner.getTokenValue();
|
|
11203
|
+
let value = Number(tokenValue);
|
|
11204
|
+
if (isNaN(value)) {
|
|
11205
|
+
handleError(2);
|
|
11206
|
+
value = 0;
|
|
11207
|
+
}
|
|
11208
|
+
onLiteralValue(value);
|
|
11209
|
+
break;
|
|
11210
|
+
case 7:
|
|
11211
|
+
onLiteralValue(null);
|
|
11212
|
+
break;
|
|
11213
|
+
case 8:
|
|
11214
|
+
onLiteralValue(true);
|
|
11215
|
+
break;
|
|
11216
|
+
case 9:
|
|
11217
|
+
onLiteralValue(false);
|
|
11218
|
+
break;
|
|
11219
|
+
default:
|
|
11220
|
+
return false;
|
|
11221
|
+
}
|
|
11222
|
+
scanNext();
|
|
11223
|
+
return true;
|
|
11224
|
+
}
|
|
11225
|
+
function parseProperty() {
|
|
11226
|
+
if (_scanner.getToken() !== 10) {
|
|
11227
|
+
handleError(3, [], [2, 5]);
|
|
11228
|
+
return false;
|
|
11229
|
+
}
|
|
11230
|
+
parseString(false);
|
|
11231
|
+
if (_scanner.getToken() === 6) {
|
|
11232
|
+
onSeparator(":");
|
|
11233
|
+
scanNext();
|
|
11234
|
+
if (!parseValue()) {
|
|
11235
|
+
handleError(4, [], [2, 5]);
|
|
11236
|
+
}
|
|
11237
|
+
} else {
|
|
11238
|
+
handleError(5, [], [2, 5]);
|
|
11239
|
+
}
|
|
11240
|
+
_jsonPath.pop();
|
|
11241
|
+
return true;
|
|
11242
|
+
}
|
|
11243
|
+
function parseObject() {
|
|
11244
|
+
onObjectBegin();
|
|
11245
|
+
scanNext();
|
|
11246
|
+
let needsComma = false;
|
|
11247
|
+
while (_scanner.getToken() !== 2 && _scanner.getToken() !== 17) {
|
|
11248
|
+
if (_scanner.getToken() === 5) {
|
|
11249
|
+
if (!needsComma) {
|
|
11250
|
+
handleError(4, [], []);
|
|
11251
|
+
}
|
|
11252
|
+
onSeparator(",");
|
|
11253
|
+
scanNext();
|
|
11254
|
+
if (_scanner.getToken() === 2 && allowTrailingComma) {
|
|
11255
|
+
break;
|
|
11256
|
+
}
|
|
11257
|
+
} else if (needsComma) {
|
|
11258
|
+
handleError(6, [], []);
|
|
11259
|
+
}
|
|
11260
|
+
if (!parseProperty()) {
|
|
11261
|
+
handleError(4, [], [2, 5]);
|
|
11262
|
+
}
|
|
11263
|
+
needsComma = true;
|
|
11264
|
+
}
|
|
11265
|
+
onObjectEnd();
|
|
11266
|
+
if (_scanner.getToken() !== 2) {
|
|
11267
|
+
handleError(7, [2], []);
|
|
11268
|
+
} else {
|
|
11269
|
+
scanNext();
|
|
11270
|
+
}
|
|
11271
|
+
return true;
|
|
11272
|
+
}
|
|
11273
|
+
function parseArray() {
|
|
11274
|
+
onArrayBegin();
|
|
11275
|
+
scanNext();
|
|
11276
|
+
let isFirstElement = true;
|
|
11277
|
+
let needsComma = false;
|
|
11278
|
+
while (_scanner.getToken() !== 4 && _scanner.getToken() !== 17) {
|
|
11279
|
+
if (_scanner.getToken() === 5) {
|
|
11280
|
+
if (!needsComma) {
|
|
11281
|
+
handleError(4, [], []);
|
|
11282
|
+
}
|
|
11283
|
+
onSeparator(",");
|
|
11284
|
+
scanNext();
|
|
11285
|
+
if (_scanner.getToken() === 4 && allowTrailingComma) {
|
|
11286
|
+
break;
|
|
11287
|
+
}
|
|
11288
|
+
} else if (needsComma) {
|
|
11289
|
+
handleError(6, [], []);
|
|
11290
|
+
}
|
|
11291
|
+
if (isFirstElement) {
|
|
11292
|
+
_jsonPath.push(0);
|
|
11293
|
+
isFirstElement = false;
|
|
11294
|
+
} else {
|
|
11295
|
+
_jsonPath[_jsonPath.length - 1]++;
|
|
11296
|
+
}
|
|
11297
|
+
if (!parseValue()) {
|
|
11298
|
+
handleError(4, [], [4, 5]);
|
|
11299
|
+
}
|
|
11300
|
+
needsComma = true;
|
|
11301
|
+
}
|
|
11302
|
+
onArrayEnd();
|
|
11303
|
+
if (!isFirstElement) {
|
|
11304
|
+
_jsonPath.pop();
|
|
11305
|
+
}
|
|
11306
|
+
if (_scanner.getToken() !== 4) {
|
|
11307
|
+
handleError(8, [4], []);
|
|
11308
|
+
} else {
|
|
11309
|
+
scanNext();
|
|
11310
|
+
}
|
|
11311
|
+
return true;
|
|
11312
|
+
}
|
|
11313
|
+
function parseValue() {
|
|
11314
|
+
switch (_scanner.getToken()) {
|
|
11315
|
+
case 3:
|
|
11316
|
+
return parseArray();
|
|
11317
|
+
case 1:
|
|
11318
|
+
return parseObject();
|
|
11319
|
+
case 10:
|
|
11320
|
+
return parseString(true);
|
|
11321
|
+
default:
|
|
11322
|
+
return parseLiteral();
|
|
11323
|
+
}
|
|
11324
|
+
}
|
|
11325
|
+
scanNext();
|
|
11326
|
+
if (_scanner.getToken() === 17) {
|
|
11327
|
+
if (options.allowEmptyContent) {
|
|
11328
|
+
return true;
|
|
11329
|
+
}
|
|
11330
|
+
handleError(4, [], []);
|
|
11331
|
+
return false;
|
|
11332
|
+
}
|
|
11333
|
+
if (!parseValue()) {
|
|
11334
|
+
handleError(4, [], []);
|
|
11335
|
+
return false;
|
|
11336
|
+
}
|
|
11337
|
+
if (_scanner.getToken() !== 17) {
|
|
11338
|
+
handleError(9, [], []);
|
|
11339
|
+
}
|
|
11340
|
+
return true;
|
|
11341
|
+
}
|
|
11342
|
+
|
|
11343
|
+
// node_modules/jsonc-parser/lib/esm/main.js
|
|
11344
|
+
var ScanError;
|
|
11345
|
+
(function(ScanError2) {
|
|
11346
|
+
ScanError2[ScanError2["None"] = 0] = "None";
|
|
11347
|
+
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
11348
|
+
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
11349
|
+
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
11350
|
+
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
11351
|
+
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
11352
|
+
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
11353
|
+
})(ScanError || (ScanError = {}));
|
|
11354
|
+
var SyntaxKind;
|
|
11355
|
+
(function(SyntaxKind2) {
|
|
11356
|
+
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
11357
|
+
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
11358
|
+
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
11359
|
+
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
11360
|
+
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
11361
|
+
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
11362
|
+
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
11363
|
+
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
11364
|
+
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
11365
|
+
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
11366
|
+
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
11367
|
+
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
11368
|
+
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
11369
|
+
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
11370
|
+
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
11371
|
+
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
11372
|
+
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
11373
|
+
})(SyntaxKind || (SyntaxKind = {}));
|
|
11374
|
+
var parse2 = parse;
|
|
11375
|
+
var ParseErrorCode;
|
|
11376
|
+
(function(ParseErrorCode2) {
|
|
11377
|
+
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
11378
|
+
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
11379
|
+
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
11380
|
+
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
11381
|
+
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
11382
|
+
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
11383
|
+
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
11384
|
+
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
11385
|
+
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
11386
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
11387
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
11388
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
11389
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
11390
|
+
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
11391
|
+
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
11392
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
11393
|
+
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
11394
|
+
|
|
11395
|
+
// src/config-loader.ts
|
|
11396
|
+
function parseConfigJson(content) {
|
|
11397
|
+
const errors = [];
|
|
11398
|
+
const result = parse2(content, errors, { allowTrailingComma: true });
|
|
11399
|
+
if (errors.length > 0) {
|
|
11400
|
+
throw new Error(`Invalid JSON/JSONC: ${errors.length} parse error(s)`);
|
|
11401
|
+
}
|
|
11402
|
+
return result;
|
|
11403
|
+
}
|
|
11404
|
+
function resolveConfigFileSync(baseDir, baseName) {
|
|
11405
|
+
const jsoncPath = join(baseDir, `${baseName}.jsonc`);
|
|
11406
|
+
if (existsSync(jsoncPath)) {
|
|
11407
|
+
return jsoncPath;
|
|
11408
|
+
}
|
|
11409
|
+
const jsonPath = join(baseDir, `${baseName}.json`);
|
|
11410
|
+
if (existsSync(jsonPath)) {
|
|
11411
|
+
return jsonPath;
|
|
11412
|
+
}
|
|
11413
|
+
return null;
|
|
11414
|
+
}
|
|
11415
|
+
async function readConfigFileAsync(baseDir, baseName) {
|
|
11416
|
+
try {
|
|
11417
|
+
return await readFile(join(baseDir, `${baseName}.jsonc`), "utf-8");
|
|
11418
|
+
} catch {}
|
|
11419
|
+
try {
|
|
11420
|
+
return await readFile(join(baseDir, `${baseName}.json`), "utf-8");
|
|
11421
|
+
} catch {
|
|
11422
|
+
return null;
|
|
11423
|
+
}
|
|
11424
|
+
}
|
|
11425
|
+
function loadOpencodeConfig(configDir) {
|
|
11426
|
+
const baseDir = configDir ?? join(homedir(), ".config", "opencode");
|
|
11427
|
+
try {
|
|
11428
|
+
const configPath = resolveConfigFileSync(baseDir, "opencode");
|
|
11429
|
+
if (!configPath)
|
|
11430
|
+
return null;
|
|
11431
|
+
const content = readFileSync(configPath, "utf-8");
|
|
11432
|
+
return parseConfigJson(content);
|
|
11433
|
+
} catch {
|
|
11434
|
+
return null;
|
|
11435
|
+
}
|
|
11436
|
+
}
|
|
11437
|
+
function loadAvailableModels(configDir) {
|
|
11438
|
+
const availableModels = new Set;
|
|
11439
|
+
const config2 = loadOpencodeConfig(configDir);
|
|
11440
|
+
if (config2?.provider) {
|
|
11441
|
+
for (const [providerId, providerConfig] of Object.entries(config2.provider)) {
|
|
11442
|
+
if (providerConfig.models) {
|
|
11443
|
+
for (const modelId of Object.keys(providerConfig.models)) {
|
|
11444
|
+
availableModels.add(`${providerId}/${modelId}`);
|
|
11445
|
+
}
|
|
11446
|
+
}
|
|
11447
|
+
}
|
|
11448
|
+
}
|
|
11449
|
+
return availableModels;
|
|
11450
|
+
}
|
|
11451
|
+
function loadDefaultModel(configDir) {
|
|
11452
|
+
const config2 = loadOpencodeConfig(configDir);
|
|
11453
|
+
return config2?.model ?? null;
|
|
11454
|
+
}
|
|
11455
|
+
var SAFE_AGENT_PROPERTIES = ["model", "temperature", "maxTokens", "thinking"];
|
|
11456
|
+
var BUILTIN_MODELS = new Set(["opencode/big-pickle"]);
|
|
11457
|
+
async function loadMicodeConfig(configDir) {
|
|
11458
|
+
const baseDir = configDir ?? join(homedir(), ".config", "opencode");
|
|
11459
|
+
try {
|
|
11460
|
+
const content = await readConfigFileAsync(baseDir, "micode");
|
|
11461
|
+
if (!content)
|
|
11462
|
+
return null;
|
|
11463
|
+
const parsed = parseConfigJson(content);
|
|
11464
|
+
const result = {};
|
|
11465
|
+
if (parsed.agents && typeof parsed.agents === "object") {
|
|
11466
|
+
const sanitizedAgents = {};
|
|
11467
|
+
for (const [agentName, agentConfig] of Object.entries(parsed.agents)) {
|
|
11468
|
+
if (agentConfig && typeof agentConfig === "object") {
|
|
11469
|
+
const sanitized = {};
|
|
11470
|
+
const config2 = agentConfig;
|
|
11471
|
+
for (const prop of SAFE_AGENT_PROPERTIES) {
|
|
11472
|
+
if (prop in config2) {
|
|
11473
|
+
sanitized[prop] = config2[prop];
|
|
11474
|
+
}
|
|
11475
|
+
}
|
|
11476
|
+
sanitizedAgents[agentName] = sanitized;
|
|
11477
|
+
}
|
|
11478
|
+
}
|
|
11479
|
+
result.agents = sanitizedAgents;
|
|
11480
|
+
}
|
|
11481
|
+
if (parsed.features && typeof parsed.features === "object") {
|
|
11482
|
+
const features = parsed.features;
|
|
11483
|
+
result.features = {
|
|
11484
|
+
mindmodelInjection: features.mindmodelInjection === true
|
|
11485
|
+
};
|
|
11486
|
+
}
|
|
11487
|
+
if (typeof parsed.compactionThreshold === "number") {
|
|
11488
|
+
const threshold = parsed.compactionThreshold;
|
|
11489
|
+
if (threshold >= 0 && threshold <= 1) {
|
|
11490
|
+
result.compactionThreshold = threshold;
|
|
11491
|
+
}
|
|
11492
|
+
}
|
|
11493
|
+
if (parsed.fragments && typeof parsed.fragments === "object") {
|
|
11494
|
+
const fragments = parsed.fragments;
|
|
11495
|
+
const sanitizedFragments = {};
|
|
11496
|
+
for (const [agentName, fragmentList] of Object.entries(fragments)) {
|
|
11497
|
+
if (Array.isArray(fragmentList)) {
|
|
11498
|
+
const validFragments = fragmentList.filter((f) => typeof f === "string" && f.trim().length > 0);
|
|
11499
|
+
if (validFragments.length > 0) {
|
|
11500
|
+
sanitizedFragments[agentName] = validFragments;
|
|
11501
|
+
}
|
|
11502
|
+
}
|
|
11503
|
+
}
|
|
11504
|
+
result.fragments = sanitizedFragments;
|
|
11505
|
+
}
|
|
11506
|
+
return result;
|
|
11507
|
+
} catch {
|
|
11508
|
+
return null;
|
|
11509
|
+
}
|
|
11510
|
+
}
|
|
11511
|
+
function loadModelContextLimits(configDir) {
|
|
11512
|
+
const limits = new Map;
|
|
11513
|
+
const baseDir = configDir ?? join(homedir(), ".config", "opencode");
|
|
11514
|
+
try {
|
|
11515
|
+
const configPath = resolveConfigFileSync(baseDir, "opencode");
|
|
11516
|
+
if (!configPath)
|
|
11517
|
+
return limits;
|
|
11518
|
+
const content = readFileSync(configPath, "utf-8");
|
|
11519
|
+
const config2 = parseConfigJson(content);
|
|
11520
|
+
if (config2.provider) {
|
|
11521
|
+
for (const [providerId, providerConfig] of Object.entries(config2.provider)) {
|
|
11522
|
+
if (providerConfig.models) {
|
|
11523
|
+
for (const [modelId, modelConfig] of Object.entries(providerConfig.models)) {
|
|
11524
|
+
const contextLimit = modelConfig?.limit?.context;
|
|
11525
|
+
if (typeof contextLimit === "number" && contextLimit > 0) {
|
|
11526
|
+
limits.set(`${providerId}/${modelId}`, contextLimit);
|
|
11527
|
+
}
|
|
11528
|
+
}
|
|
11529
|
+
}
|
|
11530
|
+
}
|
|
11531
|
+
}
|
|
11532
|
+
} catch {}
|
|
11533
|
+
return limits;
|
|
11534
|
+
}
|
|
11535
|
+
function mergeAgentConfigs(pluginAgents, userConfig, availableModels, defaultModel) {
|
|
11536
|
+
const models = availableModels ?? loadAvailableModels();
|
|
11537
|
+
const shouldValidateModels = models.size > 0;
|
|
11538
|
+
const opencodeDefaultModel = defaultModel ?? loadDefaultModel();
|
|
11539
|
+
const isValidModel = (model) => {
|
|
11540
|
+
if (BUILTIN_MODELS.has(model))
|
|
11541
|
+
return true;
|
|
11542
|
+
if (!shouldValidateModels)
|
|
11543
|
+
return true;
|
|
11544
|
+
return models.has(model);
|
|
11545
|
+
};
|
|
11546
|
+
const merged = {};
|
|
11547
|
+
for (const [name, agentConfig] of Object.entries(pluginAgents)) {
|
|
11548
|
+
const userOverride = userConfig?.agents?.[name];
|
|
11549
|
+
let finalConfig = { ...agentConfig };
|
|
11550
|
+
if (opencodeDefaultModel && isValidModel(opencodeDefaultModel)) {
|
|
11551
|
+
finalConfig = { ...finalConfig, model: opencodeDefaultModel };
|
|
11552
|
+
}
|
|
11553
|
+
if (userOverride) {
|
|
11554
|
+
if (userOverride.model) {
|
|
11555
|
+
if (isValidModel(userOverride.model)) {
|
|
11556
|
+
finalConfig = { ...finalConfig, ...userOverride };
|
|
11557
|
+
} else {
|
|
11558
|
+
const fallbackModel = finalConfig.model || "DEFAULT_MODEL";
|
|
11559
|
+
console.warn(`[micode] Model "${userOverride.model}" for agent "${name}" is not available. Using ${fallbackModel}.`);
|
|
11560
|
+
const { model: _ignored, ...safeOverrides } = userOverride;
|
|
11561
|
+
finalConfig = { ...finalConfig, ...safeOverrides };
|
|
11562
|
+
}
|
|
11563
|
+
} else {
|
|
11564
|
+
finalConfig = { ...finalConfig, ...userOverride };
|
|
11565
|
+
}
|
|
11566
|
+
}
|
|
11567
|
+
merged[name] = finalConfig;
|
|
11568
|
+
}
|
|
11569
|
+
return merged;
|
|
11570
|
+
}
|
|
11571
|
+
|
|
11572
|
+
// src/hooks/artifact-auto-index.ts
|
|
11573
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
11574
|
+
|
|
11575
|
+
// src/tools/artifact-index/index.ts
|
|
11576
|
+
import { Database } from "bun:sqlite";
|
|
11577
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2 } from "fs";
|
|
11578
|
+
import { homedir as homedir2 } from "os";
|
|
11579
|
+
import { dirname, join as join2 } from "path";
|
|
11580
|
+
var DEFAULT_DB_DIR = join2(homedir2(), ".config", "opencode", "artifact-index");
|
|
11581
|
+
var DB_NAME = "context.db";
|
|
11582
|
+
|
|
11583
|
+
class ArtifactIndex {
|
|
11584
|
+
db = null;
|
|
11585
|
+
dbPath;
|
|
11586
|
+
constructor(dbDir = DEFAULT_DB_DIR) {
|
|
11587
|
+
this.dbPath = join2(dbDir, DB_NAME);
|
|
11588
|
+
}
|
|
11589
|
+
async initialize() {
|
|
11590
|
+
const dir = dirname(this.dbPath);
|
|
11591
|
+
if (!existsSync2(dir)) {
|
|
11592
|
+
mkdirSync(dir, { recursive: true });
|
|
11593
|
+
}
|
|
11594
|
+
this.db = new Database(this.dbPath);
|
|
11595
|
+
const schemaPath = join2(dirname(import.meta.path), "schema.sql");
|
|
11596
|
+
let schema;
|
|
11597
|
+
try {
|
|
11598
|
+
schema = readFileSync2(schemaPath, "utf-8");
|
|
11599
|
+
} catch {
|
|
11600
|
+
schema = this.getInlineSchema();
|
|
11601
|
+
}
|
|
11602
|
+
this.db.exec(schema);
|
|
11603
|
+
}
|
|
11604
|
+
getInlineSchema() {
|
|
11605
|
+
return `
|
|
11606
|
+
CREATE TABLE IF NOT EXISTS plans (
|
|
11607
|
+
id TEXT PRIMARY KEY,
|
|
11608
|
+
title TEXT,
|
|
11609
|
+
file_path TEXT UNIQUE NOT NULL,
|
|
11610
|
+
overview TEXT,
|
|
11611
|
+
approach TEXT,
|
|
10694
11612
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
10695
11613
|
indexed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
10696
11614
|
);
|
|
@@ -11026,79 +11944,16 @@ function createArtifactAutoIndexHook(_ctx) {
|
|
|
11026
11944
|
await index.indexPlan(record);
|
|
11027
11945
|
return;
|
|
11028
11946
|
}
|
|
11029
|
-
} catch (e) {
|
|
11030
|
-
log.error("artifact-auto-index", `Error indexing ${filePath}`, e);
|
|
11031
|
-
}
|
|
11032
|
-
}
|
|
11033
|
-
};
|
|
11034
|
-
}
|
|
11035
|
-
|
|
11036
|
-
// src/hooks/auto-compact.ts
|
|
11037
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
11038
|
-
import { join as join3 } from "path";
|
|
11039
|
-
|
|
11040
|
-
// src/utils/config.ts
|
|
11041
|
-
var config = {
|
|
11042
|
-
compaction: {
|
|
11043
|
-
threshold: 0.7,
|
|
11044
|
-
cooldownMs: 120000,
|
|
11045
|
-
timeoutMs: 120000
|
|
11046
|
-
},
|
|
11047
|
-
contextWindow: {
|
|
11048
|
-
warningThreshold: 0.7,
|
|
11049
|
-
criticalThreshold: 0.85,
|
|
11050
|
-
warningCooldownMs: 120000
|
|
11051
|
-
},
|
|
11052
|
-
tokens: {
|
|
11053
|
-
charsPerToken: 4,
|
|
11054
|
-
defaultContextLimit: 200000,
|
|
11055
|
-
defaultMaxOutputTokens: 50000,
|
|
11056
|
-
safetyMargin: 0.5,
|
|
11057
|
-
preserveHeaderLines: 3
|
|
11058
|
-
},
|
|
11059
|
-
paths: {
|
|
11060
|
-
ledgerDir: "thoughts/ledgers",
|
|
11061
|
-
ledgerPrefix: "CONTINUITY_",
|
|
11062
|
-
rootContextFiles: ["README.md", "ARCHITECTURE.md", "CODE_STYLE.md"],
|
|
11063
|
-
dirContextFiles: ["README.md"],
|
|
11064
|
-
planPattern: /thoughts\/shared\/plans\/.*\.md$/,
|
|
11065
|
-
ledgerPattern: /thoughts\/ledgers\/CONTINUITY_.*\.md$/,
|
|
11066
|
-
mindmodelDir: ".mindmodel",
|
|
11067
|
-
mindmodelManifest: "manifest.yaml",
|
|
11068
|
-
mindmodelSystem: "system.md"
|
|
11069
|
-
},
|
|
11070
|
-
timeouts: {
|
|
11071
|
-
btcaMs: 120000,
|
|
11072
|
-
toastSuccessMs: 3000,
|
|
11073
|
-
toastWarningMs: 4000,
|
|
11074
|
-
toastErrorMs: 5000
|
|
11075
|
-
},
|
|
11076
|
-
limits: {
|
|
11077
|
-
largeFileBytes: 100 * 1024,
|
|
11078
|
-
maxLinesNoExtract: 200,
|
|
11079
|
-
ptyMaxBufferLines: 50000,
|
|
11080
|
-
ptyDefaultReadLimit: 500,
|
|
11081
|
-
ptyMaxLineLength: 2000,
|
|
11082
|
-
astGrepMaxMatches: 100,
|
|
11083
|
-
contextCacheTtlMs: 30000,
|
|
11084
|
-
contextCacheMaxSize: 100
|
|
11085
|
-
},
|
|
11086
|
-
octto: {
|
|
11087
|
-
answerTimeoutMs: 5 * 60 * 1000,
|
|
11088
|
-
reviewTimeoutMs: 10 * 60 * 1000,
|
|
11089
|
-
maxIterations: 50,
|
|
11090
|
-
maxQuestions: 15,
|
|
11091
|
-
stateDir: "thoughts/brainstorms",
|
|
11092
|
-
bindAddress: "127.0.0.1",
|
|
11093
|
-
allowRemoteBind: false
|
|
11094
|
-
},
|
|
11095
|
-
mindmodel: {
|
|
11096
|
-
overrideLogFile: "overrides.log",
|
|
11097
|
-
reviewMaxRetries: 1,
|
|
11098
|
-
reviewEnabled: true,
|
|
11099
|
-
categoryGroups: ["stack", "architecture", "patterns", "style", "components", "domain", "ops"]
|
|
11100
|
-
}
|
|
11101
|
-
};
|
|
11947
|
+
} catch (e) {
|
|
11948
|
+
log.error("artifact-auto-index", `Error indexing ${filePath}`, e);
|
|
11949
|
+
}
|
|
11950
|
+
}
|
|
11951
|
+
};
|
|
11952
|
+
}
|
|
11953
|
+
|
|
11954
|
+
// src/hooks/auto-compact.ts
|
|
11955
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
11956
|
+
import { join as join3 } from "path";
|
|
11102
11957
|
|
|
11103
11958
|
// src/utils/errors.ts
|
|
11104
11959
|
function extractErrorMessage(e) {
|
|
@@ -11720,7 +12575,7 @@ function string(message$1) {
|
|
|
11720
12575
|
}
|
|
11721
12576
|
};
|
|
11722
12577
|
}
|
|
11723
|
-
function
|
|
12578
|
+
function parse3(schema, input, config$1) {
|
|
11724
12579
|
const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1));
|
|
11725
12580
|
if (dataset.issues)
|
|
11726
12581
|
throw new ValiError(dataset.issues);
|
|
@@ -11764,7 +12619,7 @@ var lexer = require_lexer();
|
|
|
11764
12619
|
var lineCounter = require_line_counter();
|
|
11765
12620
|
var parser = require_parser();
|
|
11766
12621
|
var publicApi = require_public_api();
|
|
11767
|
-
var
|
|
12622
|
+
var visit2 = require_visit();
|
|
11768
12623
|
var $Composer = composer.Composer;
|
|
11769
12624
|
var $Document = Document.Document;
|
|
11770
12625
|
var $Schema = Schema.Schema;
|
|
@@ -11791,8 +12646,8 @@ var $parse = publicApi.parse;
|
|
|
11791
12646
|
var $parseAllDocuments = publicApi.parseAllDocuments;
|
|
11792
12647
|
var $parseDocument = publicApi.parseDocument;
|
|
11793
12648
|
var $stringify = publicApi.stringify;
|
|
11794
|
-
var $visit =
|
|
11795
|
-
var $visitAsync =
|
|
12649
|
+
var $visit = visit2.visit;
|
|
12650
|
+
var $visitAsync = visit2.visitAsync;
|
|
11796
12651
|
|
|
11797
12652
|
// src/mindmodel/types.ts
|
|
11798
12653
|
var CategorySchema = object({
|
|
@@ -11807,7 +12662,7 @@ var ManifestSchema = object({
|
|
|
11807
12662
|
});
|
|
11808
12663
|
function parseManifest(yamlContent) {
|
|
11809
12664
|
const parsed = $parse(yamlContent);
|
|
11810
|
-
return
|
|
12665
|
+
return parse3(ManifestSchema, parsed);
|
|
11811
12666
|
}
|
|
11812
12667
|
|
|
11813
12668
|
// src/mindmodel/loader.ts
|
|
@@ -11827,7 +12682,7 @@ async function loadMindmodel(projectDir) {
|
|
|
11827
12682
|
manifest
|
|
11828
12683
|
};
|
|
11829
12684
|
} catch (error) {
|
|
11830
|
-
|
|
12685
|
+
log.warn("mindmodel", `Failed to load manifest: ${error}`);
|
|
11831
12686
|
return null;
|
|
11832
12687
|
}
|
|
11833
12688
|
}
|
|
@@ -11846,7 +12701,7 @@ async function loadExamples(mindmodel, categoryPaths) {
|
|
|
11846
12701
|
content
|
|
11847
12702
|
});
|
|
11848
12703
|
} catch {
|
|
11849
|
-
|
|
12704
|
+
log.warn("mindmodel", `Failed to load example: ${categoryPath}`);
|
|
11850
12705
|
}
|
|
11851
12706
|
}
|
|
11852
12707
|
return examples;
|
|
@@ -12205,6 +13060,165 @@ function createContextWindowMonitorHook(ctx, hookConfig) {
|
|
|
12205
13060
|
};
|
|
12206
13061
|
}
|
|
12207
13062
|
|
|
13063
|
+
// src/hooks/fetch-tracker.ts
|
|
13064
|
+
var FETCH_TOOLS = new Set(["webfetch", "context7_query-docs", "context7_resolve-library-id", "btca_ask"]);
|
|
13065
|
+
|
|
13066
|
+
class LRUCache {
|
|
13067
|
+
maxSize;
|
|
13068
|
+
cache = new Map;
|
|
13069
|
+
constructor(maxSize) {
|
|
13070
|
+
this.maxSize = maxSize;
|
|
13071
|
+
}
|
|
13072
|
+
get(key) {
|
|
13073
|
+
const value = this.cache.get(key);
|
|
13074
|
+
if (value !== undefined) {
|
|
13075
|
+
this.cache.delete(key);
|
|
13076
|
+
this.cache.set(key, value);
|
|
13077
|
+
}
|
|
13078
|
+
return value;
|
|
13079
|
+
}
|
|
13080
|
+
set(key, value) {
|
|
13081
|
+
if (this.cache.has(key)) {
|
|
13082
|
+
this.cache.delete(key);
|
|
13083
|
+
} else if (this.cache.size >= this.maxSize) {
|
|
13084
|
+
const firstKey = this.cache.keys().next().value;
|
|
13085
|
+
if (firstKey !== undefined)
|
|
13086
|
+
this.cache.delete(firstKey);
|
|
13087
|
+
}
|
|
13088
|
+
this.cache.set(key, value);
|
|
13089
|
+
}
|
|
13090
|
+
delete(key) {
|
|
13091
|
+
this.cache.delete(key);
|
|
13092
|
+
}
|
|
13093
|
+
clear() {
|
|
13094
|
+
this.cache.clear();
|
|
13095
|
+
}
|
|
13096
|
+
}
|
|
13097
|
+
var sessionCallCounts = new Map;
|
|
13098
|
+
var sessionCaches = new Map;
|
|
13099
|
+
function normalizeKey(tool, args) {
|
|
13100
|
+
if (!FETCH_TOOLS.has(tool) || !args)
|
|
13101
|
+
return null;
|
|
13102
|
+
try {
|
|
13103
|
+
switch (tool) {
|
|
13104
|
+
case "webfetch": {
|
|
13105
|
+
const rawUrl = args.url;
|
|
13106
|
+
if (!rawUrl)
|
|
13107
|
+
return null;
|
|
13108
|
+
try {
|
|
13109
|
+
const parsed = new URL(rawUrl);
|
|
13110
|
+
parsed.searchParams.sort();
|
|
13111
|
+
return `webfetch|${parsed.toString()}`;
|
|
13112
|
+
} catch {
|
|
13113
|
+
return `webfetch|${rawUrl}`;
|
|
13114
|
+
}
|
|
13115
|
+
}
|
|
13116
|
+
case "context7_query-docs": {
|
|
13117
|
+
const libraryId = args.libraryId;
|
|
13118
|
+
const query = args.query;
|
|
13119
|
+
if (!libraryId || !query)
|
|
13120
|
+
return null;
|
|
13121
|
+
return `context7_query-docs|${libraryId}|${query}`;
|
|
13122
|
+
}
|
|
13123
|
+
case "context7_resolve-library-id": {
|
|
13124
|
+
const libraryName = args.libraryName;
|
|
13125
|
+
const query = args.query;
|
|
13126
|
+
if (!libraryName || !query)
|
|
13127
|
+
return null;
|
|
13128
|
+
return `context7_resolve-library-id|${libraryName}|${query}`;
|
|
13129
|
+
}
|
|
13130
|
+
case "btca_ask": {
|
|
13131
|
+
const tech = args.tech;
|
|
13132
|
+
const question = args.question;
|
|
13133
|
+
if (!tech || !question)
|
|
13134
|
+
return null;
|
|
13135
|
+
return `btca_ask|${tech}|${question}`;
|
|
13136
|
+
}
|
|
13137
|
+
default:
|
|
13138
|
+
return null;
|
|
13139
|
+
}
|
|
13140
|
+
} catch (error) {
|
|
13141
|
+
log.warn("hooks.fetch-tracker", `Key normalization failed: ${error instanceof Error ? error.message : "unknown"}`);
|
|
13142
|
+
return null;
|
|
13143
|
+
}
|
|
13144
|
+
}
|
|
13145
|
+
function clearSession(sessionID) {
|
|
13146
|
+
sessionCallCounts.delete(sessionID);
|
|
13147
|
+
sessionCaches.delete(sessionID);
|
|
13148
|
+
}
|
|
13149
|
+
function getOrCreateCounts(sessionID) {
|
|
13150
|
+
let counts = sessionCallCounts.get(sessionID);
|
|
13151
|
+
if (!counts) {
|
|
13152
|
+
counts = new Map;
|
|
13153
|
+
sessionCallCounts.set(sessionID, counts);
|
|
13154
|
+
}
|
|
13155
|
+
return counts;
|
|
13156
|
+
}
|
|
13157
|
+
function getOrCreateCache(sessionID) {
|
|
13158
|
+
let cache = sessionCaches.get(sessionID);
|
|
13159
|
+
if (!cache) {
|
|
13160
|
+
cache = new LRUCache(config.fetch.cacheMaxEntries);
|
|
13161
|
+
sessionCaches.set(sessionID, cache);
|
|
13162
|
+
}
|
|
13163
|
+
return cache;
|
|
13164
|
+
}
|
|
13165
|
+
function incrementCount(sessionID, key) {
|
|
13166
|
+
const counts = getOrCreateCounts(sessionID);
|
|
13167
|
+
const current = counts.get(key) ?? 0;
|
|
13168
|
+
const next = current + 1;
|
|
13169
|
+
counts.set(key, next);
|
|
13170
|
+
return next;
|
|
13171
|
+
}
|
|
13172
|
+
function isCacheExpired(entry) {
|
|
13173
|
+
return Date.now() - entry.timestamp > config.fetch.cacheTtlMs;
|
|
13174
|
+
}
|
|
13175
|
+
function createFetchTrackerHook(_ctx) {
|
|
13176
|
+
return {
|
|
13177
|
+
"tool.execute.after": async (input, output) => {
|
|
13178
|
+
try {
|
|
13179
|
+
if (!FETCH_TOOLS.has(input.tool))
|
|
13180
|
+
return;
|
|
13181
|
+
const key = normalizeKey(input.tool, input.args);
|
|
13182
|
+
if (!key)
|
|
13183
|
+
return;
|
|
13184
|
+
const count = incrementCount(input.sessionID, key);
|
|
13185
|
+
if (count > config.fetch.maxCallsPerResource) {
|
|
13186
|
+
output.output = `<fetch-blocked>This resource has been fetched ${count} times this session. The content is already available in the conversation above. Use the information already available instead of re-fetching.</fetch-blocked>`;
|
|
13187
|
+
return;
|
|
13188
|
+
}
|
|
13189
|
+
const cache = getOrCreateCache(input.sessionID);
|
|
13190
|
+
const cached = cache.get(key);
|
|
13191
|
+
if (count > 1 && cached && !isCacheExpired(cached)) {
|
|
13192
|
+
let cachedOutput = `<from-cache>Returning cached result (fetched ${count} time${count !== 1 ? "s" : ""} previously).</from-cache>
|
|
13193
|
+
|
|
13194
|
+
${cached.content}`;
|
|
13195
|
+
if (count >= config.fetch.warnThreshold) {
|
|
13196
|
+
cachedOutput += `
|
|
13197
|
+
|
|
13198
|
+
<fetch-warning>You have fetched this resource ${count} times. The content is cached and identical. Consider using the information you already have instead of re-fetching.</fetch-warning>`;
|
|
13199
|
+
}
|
|
13200
|
+
output.output = cachedOutput;
|
|
13201
|
+
} else {
|
|
13202
|
+
if (output.output) {
|
|
13203
|
+
cache.set(key, { content: output.output, timestamp: Date.now() });
|
|
13204
|
+
}
|
|
13205
|
+
}
|
|
13206
|
+
} catch (error) {
|
|
13207
|
+
log.warn("hooks.fetch-tracker", `After hook error: ${error instanceof Error ? error.message : "unknown"}`);
|
|
13208
|
+
}
|
|
13209
|
+
},
|
|
13210
|
+
event: async ({ event }) => {
|
|
13211
|
+
if (event.type === "session.deleted") {
|
|
13212
|
+
const props = event.properties;
|
|
13213
|
+
if (props?.info?.id) {
|
|
13214
|
+
clearSession(props.info.id);
|
|
13215
|
+
}
|
|
13216
|
+
}
|
|
13217
|
+
},
|
|
13218
|
+
cleanupSession: clearSession
|
|
13219
|
+
};
|
|
13220
|
+
}
|
|
13221
|
+
|
|
12208
13222
|
// src/hooks/file-ops-tracker.ts
|
|
12209
13223
|
var sessionFileOps = new Map;
|
|
12210
13224
|
function getOrCreateOps(sessionID) {
|
|
@@ -12495,7 +13509,7 @@ __export(exports_external, {
|
|
|
12495
13509
|
pipe: () => pipe2,
|
|
12496
13510
|
partialRecord: () => partialRecord,
|
|
12497
13511
|
parseAsync: () => parseAsync2,
|
|
12498
|
-
parse: () =>
|
|
13512
|
+
parse: () => parse6,
|
|
12499
13513
|
overwrite: () => _overwrite,
|
|
12500
13514
|
optional: () => optional2,
|
|
12501
13515
|
object: () => object2,
|
|
@@ -12685,7 +13699,7 @@ __export(exports_core2, {
|
|
|
12685
13699
|
regexes: () => exports_regexes,
|
|
12686
13700
|
prettifyError: () => prettifyError,
|
|
12687
13701
|
parseAsync: () => parseAsync,
|
|
12688
|
-
parse: () =>
|
|
13702
|
+
parse: () => parse4,
|
|
12689
13703
|
locales: () => exports_locales,
|
|
12690
13704
|
isValidJWT: () => isValidJWT,
|
|
12691
13705
|
isValidBase64URL: () => isValidBase64URL,
|
|
@@ -13784,7 +14798,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
13784
14798
|
}
|
|
13785
14799
|
return result.value;
|
|
13786
14800
|
};
|
|
13787
|
-
var
|
|
14801
|
+
var parse4 = /* @__PURE__ */ _parse($ZodRealError);
|
|
13788
14802
|
var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
13789
14803
|
const ctx = _ctx ? Object.assign(_ctx, { async: true }) : { async: true };
|
|
13790
14804
|
let result = schema._zod.run({ value, issues: [] }, ctx);
|
|
@@ -16302,10 +17316,10 @@ var $ZodFunction = /* @__PURE__ */ $constructor("$ZodFunction", (inst, def) => {
|
|
|
16302
17316
|
throw new Error("implement() must be called with a function");
|
|
16303
17317
|
}
|
|
16304
17318
|
return function(...args) {
|
|
16305
|
-
const parsedArgs = inst._def.input ?
|
|
17319
|
+
const parsedArgs = inst._def.input ? parse4(inst._def.input, args) : args;
|
|
16306
17320
|
const result = Reflect.apply(func, this, parsedArgs);
|
|
16307
17321
|
if (inst._def.output) {
|
|
16308
|
-
return
|
|
17322
|
+
return parse4(inst._def.output, result);
|
|
16309
17323
|
}
|
|
16310
17324
|
return result;
|
|
16311
17325
|
};
|
|
@@ -22814,13 +23828,13 @@ function _stringbool(Classes, _params) {
|
|
|
22814
23828
|
});
|
|
22815
23829
|
return codec;
|
|
22816
23830
|
}
|
|
22817
|
-
function _stringFormat(Class2,
|
|
23831
|
+
function _stringFormat(Class2, format2, fnOrRegex, _params = {}) {
|
|
22818
23832
|
const params = normalizeParams(_params);
|
|
22819
23833
|
const def = {
|
|
22820
23834
|
...normalizeParams(_params),
|
|
22821
23835
|
check: "string_format",
|
|
22822
23836
|
type: "string",
|
|
22823
|
-
format,
|
|
23837
|
+
format: format2,
|
|
22824
23838
|
fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
|
|
22825
23839
|
...params
|
|
22826
23840
|
};
|
|
@@ -22882,13 +23896,13 @@ class JSONSchemaGenerator {
|
|
|
22882
23896
|
case "string": {
|
|
22883
23897
|
const json = _json;
|
|
22884
23898
|
json.type = "string";
|
|
22885
|
-
const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
|
|
23899
|
+
const { minimum, maximum, format: format2, patterns, contentEncoding } = schema._zod.bag;
|
|
22886
23900
|
if (typeof minimum === "number")
|
|
22887
23901
|
json.minLength = minimum;
|
|
22888
23902
|
if (typeof maximum === "number")
|
|
22889
23903
|
json.maxLength = maximum;
|
|
22890
|
-
if (
|
|
22891
|
-
json.format = formatMap[
|
|
23904
|
+
if (format2) {
|
|
23905
|
+
json.format = formatMap[format2] ?? format2;
|
|
22892
23906
|
if (json.format === "")
|
|
22893
23907
|
delete json.format;
|
|
22894
23908
|
}
|
|
@@ -22911,8 +23925,8 @@ class JSONSchemaGenerator {
|
|
|
22911
23925
|
}
|
|
22912
23926
|
case "number": {
|
|
22913
23927
|
const json = _json;
|
|
22914
|
-
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
22915
|
-
if (typeof
|
|
23928
|
+
const { minimum, maximum, format: format2, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
23929
|
+
if (typeof format2 === "string" && format2.includes("int"))
|
|
22916
23930
|
json.type = "integer";
|
|
22917
23931
|
else
|
|
22918
23932
|
json.type = "number";
|
|
@@ -23713,7 +24727,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
|
|
|
23713
24727
|
});
|
|
23714
24728
|
|
|
23715
24729
|
// node_modules/zod/v4/classic/parse.js
|
|
23716
|
-
var
|
|
24730
|
+
var parse6 = /* @__PURE__ */ _parse(ZodRealError);
|
|
23717
24731
|
var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
23718
24732
|
var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
23719
24733
|
var safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
@@ -23747,7 +24761,7 @@ var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
|
|
|
23747
24761
|
reg.add(inst, meta);
|
|
23748
24762
|
return inst;
|
|
23749
24763
|
};
|
|
23750
|
-
inst.parse = (data, params) =>
|
|
24764
|
+
inst.parse = (data, params) => parse6(inst, data, params, { callee: inst.parse });
|
|
23751
24765
|
inst.safeParse = (data, params) => safeParse2(inst, data, params);
|
|
23752
24766
|
inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
|
|
23753
24767
|
inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params);
|
|
@@ -24012,8 +25026,8 @@ var ZodCustomStringFormat = /* @__PURE__ */ $constructor("ZodCustomStringFormat"
|
|
|
24012
25026
|
$ZodCustomStringFormat.init(inst, def);
|
|
24013
25027
|
ZodStringFormat.init(inst, def);
|
|
24014
25028
|
});
|
|
24015
|
-
function stringFormat(
|
|
24016
|
-
return _stringFormat(ZodCustomStringFormat,
|
|
25029
|
+
function stringFormat(format2, fnOrRegex, _params = {}) {
|
|
25030
|
+
return _stringFormat(ZodCustomStringFormat, format2, fnOrRegex, _params);
|
|
24017
25031
|
}
|
|
24018
25032
|
function hostname2(_params) {
|
|
24019
25033
|
return _stringFormat(ZodCustomStringFormat, "hostname", exports_regexes.hostname, _params);
|
|
@@ -24023,11 +25037,11 @@ function hex2(_params) {
|
|
|
24023
25037
|
}
|
|
24024
25038
|
function hash(alg, params) {
|
|
24025
25039
|
const enc = params?.enc ?? "hex";
|
|
24026
|
-
const
|
|
24027
|
-
const regex = exports_regexes[
|
|
25040
|
+
const format2 = `${alg}_${enc}`;
|
|
25041
|
+
const regex = exports_regexes[format2];
|
|
24028
25042
|
if (!regex)
|
|
24029
|
-
throw new Error(`Unrecognized hash format: ${
|
|
24030
|
-
return _stringFormat(ZodCustomStringFormat,
|
|
25043
|
+
throw new Error(`Unrecognized hash format: ${format2}`);
|
|
25044
|
+
return _stringFormat(ZodCustomStringFormat, format2, regex, params);
|
|
24031
25045
|
}
|
|
24032
25046
|
var ZodNumber = /* @__PURE__ */ $constructor("ZodNumber", (inst, def) => {
|
|
24033
25047
|
$ZodNumber.init(inst, def);
|
|
@@ -24802,13 +25816,13 @@ Returns relevant code examples and patterns to follow.`,
|
|
|
24802
25816
|
if (categories.length === 0) {
|
|
24803
25817
|
return "No specific patterns found for this task. Proceed using general best practices.";
|
|
24804
25818
|
}
|
|
24805
|
-
log.
|
|
25819
|
+
log.debug("mindmodel", `Matched categories: ${categories.join(", ")}`);
|
|
24806
25820
|
const examples = await loadExamples(mindmodel, categories);
|
|
24807
25821
|
if (examples.length === 0) {
|
|
24808
25822
|
return "Categories matched but no examples found. Proceed using general best practices.";
|
|
24809
25823
|
}
|
|
24810
25824
|
const formatted = formatExamplesForInjection(examples);
|
|
24811
|
-
log.
|
|
25825
|
+
log.debug("mindmodel", `Returning ${examples.length} examples`);
|
|
24812
25826
|
return formatted;
|
|
24813
25827
|
} catch (error45) {
|
|
24814
25828
|
log.warn("mindmodel", `Lookup failed: ${error45 instanceof Error ? error45.message : "unknown"}`);
|
|
@@ -24830,7 +25844,7 @@ function hashTask(task) {
|
|
|
24830
25844
|
return hash2.toString(36);
|
|
24831
25845
|
}
|
|
24832
25846
|
|
|
24833
|
-
class
|
|
25847
|
+
class LRUCache2 {
|
|
24834
25848
|
maxSize;
|
|
24835
25849
|
cache = new Map;
|
|
24836
25850
|
constructor(maxSize) {
|
|
@@ -24862,7 +25876,7 @@ function createMindmodelInjectorHook(ctx) {
|
|
|
24862
25876
|
let cachedMindmodel2;
|
|
24863
25877
|
let cachedSystemMd;
|
|
24864
25878
|
let pendingInjection = null;
|
|
24865
|
-
const matchedTasks = new
|
|
25879
|
+
const matchedTasks = new LRUCache2(2000);
|
|
24866
25880
|
async function getMindmodel2() {
|
|
24867
25881
|
if (cachedMindmodel2 === undefined) {
|
|
24868
25882
|
cachedMindmodel2 = await loadMindmodel(ctx.directory);
|
|
@@ -27957,7 +28971,7 @@ function createSessionStore(options = {}) {
|
|
|
27957
28971
|
return store;
|
|
27958
28972
|
}
|
|
27959
28973
|
// src/octto/state/persistence.ts
|
|
27960
|
-
import { existsSync as
|
|
28974
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, rmSync } from "fs";
|
|
27961
28975
|
import { join as join10 } from "path";
|
|
27962
28976
|
function validateSessionId(sessionId) {
|
|
27963
28977
|
if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) {
|
|
@@ -27970,7 +28984,7 @@ function createStatePersistence(baseDir = STATE_DIR) {
|
|
|
27970
28984
|
return join10(baseDir, `${sessionId}.json`);
|
|
27971
28985
|
}
|
|
27972
28986
|
function ensureDir() {
|
|
27973
|
-
if (!
|
|
28987
|
+
if (!existsSync3(baseDir)) {
|
|
27974
28988
|
mkdirSync2(baseDir, { recursive: true });
|
|
27975
28989
|
}
|
|
27976
28990
|
}
|
|
@@ -27983,7 +28997,7 @@ function createStatePersistence(baseDir = STATE_DIR) {
|
|
|
27983
28997
|
},
|
|
27984
28998
|
async load(sessionId) {
|
|
27985
28999
|
const filePath = getFilePath(sessionId);
|
|
27986
|
-
if (!
|
|
29000
|
+
if (!existsSync3(filePath)) {
|
|
27987
29001
|
return null;
|
|
27988
29002
|
}
|
|
27989
29003
|
const content = await Bun.file(filePath).text();
|
|
@@ -27991,12 +29005,12 @@ function createStatePersistence(baseDir = STATE_DIR) {
|
|
|
27991
29005
|
},
|
|
27992
29006
|
async delete(sessionId) {
|
|
27993
29007
|
const filePath = getFilePath(sessionId);
|
|
27994
|
-
if (
|
|
29008
|
+
if (existsSync3(filePath)) {
|
|
27995
29009
|
rmSync(filePath);
|
|
27996
29010
|
}
|
|
27997
29011
|
},
|
|
27998
29012
|
async list() {
|
|
27999
|
-
if (!
|
|
29013
|
+
if (!existsSync3(baseDir)) {
|
|
28000
29014
|
return [];
|
|
28001
29015
|
}
|
|
28002
29016
|
const files = readdirSync(baseDir);
|
|
@@ -29249,9 +30263,6 @@ function createOcttoTools(sessions, client, tracker) {
|
|
|
29249
30263
|
};
|
|
29250
30264
|
}
|
|
29251
30265
|
|
|
29252
|
-
// src/tools/pty/manager.ts
|
|
29253
|
-
import { spawn as spawn3 } from "bun-pty";
|
|
29254
|
-
|
|
29255
30266
|
// src/tools/pty/buffer.ts
|
|
29256
30267
|
var parsed = parseInt(process.env.PTY_MAX_BUFFER_LINES || "50000", 10);
|
|
29257
30268
|
var DEFAULT_MAX_LINES = isNaN(parsed) ? 50000 : parsed;
|
|
@@ -29294,7 +30305,6 @@ class RingBuffer {
|
|
|
29294
30305
|
this.lines = [];
|
|
29295
30306
|
}
|
|
29296
30307
|
}
|
|
29297
|
-
|
|
29298
30308
|
// src/tools/pty/manager.ts
|
|
29299
30309
|
function generateId2() {
|
|
29300
30310
|
const hex3 = Array.from(crypto.getRandomValues(new Uint8Array(4))).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
@@ -29303,7 +30313,19 @@ function generateId2() {
|
|
|
29303
30313
|
|
|
29304
30314
|
class PTYManager {
|
|
29305
30315
|
sessions = new Map;
|
|
30316
|
+
spawnFn = null;
|
|
30317
|
+
_available = false;
|
|
30318
|
+
init(spawnFn) {
|
|
30319
|
+
this.spawnFn = spawnFn;
|
|
30320
|
+
this._available = true;
|
|
30321
|
+
}
|
|
30322
|
+
get available() {
|
|
30323
|
+
return this._available;
|
|
30324
|
+
}
|
|
29306
30325
|
spawn(opts) {
|
|
30326
|
+
if (!this.spawnFn) {
|
|
30327
|
+
throw new Error("PTY unavailable: bun-pty native library could not be loaded. " + "Set BUN_PTY_LIB environment variable to the path of the native library " + "(e.g., .opencode/node_modules/bun-pty/rust-pty/target/release/librust_pty.dylib)");
|
|
30328
|
+
}
|
|
29307
30329
|
const id = generateId2();
|
|
29308
30330
|
const args = opts.args ?? [];
|
|
29309
30331
|
const workdir = opts.workdir ?? process.cwd();
|
|
@@ -29311,7 +30333,7 @@ class PTYManager {
|
|
|
29311
30333
|
const title = opts.title ?? (`${opts.command} ${args.join(" ")}`.trim() || `Terminal ${id.slice(-4)}`);
|
|
29312
30334
|
let ptyProcess;
|
|
29313
30335
|
try {
|
|
29314
|
-
ptyProcess =
|
|
30336
|
+
ptyProcess = this.spawnFn(opts.command, args, {
|
|
29315
30337
|
name: "xterm-256color",
|
|
29316
30338
|
cols: 120,
|
|
29317
30339
|
rows: 40,
|
|
@@ -29433,150 +30455,166 @@ class PTYManager {
|
|
|
29433
30455
|
};
|
|
29434
30456
|
}
|
|
29435
30457
|
}
|
|
29436
|
-
// src/tools/pty/
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29440
|
-
|
|
29441
|
-
|
|
29442
|
-
|
|
29443
|
-
|
|
29444
|
-
|
|
29445
|
-
|
|
29446
|
-
|
|
29447
|
-
|
|
29448
|
-
|
|
29449
|
-
|
|
29450
|
-
|
|
29451
|
-
|
|
29452
|
-
|
|
29453
|
-
|
|
29454
|
-
|
|
29455
|
-
|
|
29456
|
-
|
|
29457
|
-
|
|
29458
|
-
After spawning, use:
|
|
29459
|
-
- \`pty_write\` to send input to the PTY
|
|
29460
|
-
- \`pty_read\` to read output from the PTY
|
|
29461
|
-
- \`pty_list\` to see all active PTY sessions
|
|
29462
|
-
- \`pty_kill\` to terminate the PTY
|
|
29463
|
-
|
|
29464
|
-
Examples:
|
|
29465
|
-
- Start a dev server: command="npm", args=["run", "dev"], title="Dev Server"
|
|
29466
|
-
- Start a Python REPL: command="python3", title="Python REPL"
|
|
29467
|
-
- Run tests in watch mode: command="npm", args=["test", "--", "--watch"]`;
|
|
29468
|
-
function createPtySpawnTool(manager) {
|
|
29469
|
-
return tool({
|
|
29470
|
-
description: DESCRIPTION,
|
|
29471
|
-
args: {
|
|
29472
|
-
command: tool.schema.string().describe("The command/executable to run"),
|
|
29473
|
-
args: tool.schema.array(tool.schema.string()).optional().describe("Arguments to pass to the command"),
|
|
29474
|
-
workdir: tool.schema.string().optional().describe("Working directory for the PTY session"),
|
|
29475
|
-
env: tool.schema.record(tool.schema.string(), tool.schema.string()).optional().describe("Additional environment variables"),
|
|
29476
|
-
title: tool.schema.string().optional().describe("Human-readable title for the session"),
|
|
29477
|
-
description: tool.schema.string().optional().describe("Clear, concise description of what this PTY session is for in 5-10 words")
|
|
29478
|
-
},
|
|
29479
|
-
execute: async (args, ctx) => {
|
|
29480
|
-
const info = manager.spawn({
|
|
29481
|
-
command: args.command,
|
|
29482
|
-
args: args.args,
|
|
29483
|
-
workdir: args.workdir,
|
|
29484
|
-
env: args.env,
|
|
29485
|
-
title: args.title,
|
|
29486
|
-
parentSessionId: ctx.sessionID
|
|
29487
|
-
});
|
|
29488
|
-
const output = [
|
|
29489
|
-
`<pty_spawned>`,
|
|
29490
|
-
`ID: ${info.id}`,
|
|
29491
|
-
`Title: ${info.title}`,
|
|
29492
|
-
`Command: ${info.command} ${info.args.join(" ")}`,
|
|
29493
|
-
`Workdir: ${info.workdir}`,
|
|
29494
|
-
`PID: ${info.pid}`,
|
|
29495
|
-
`Status: ${info.status}`,
|
|
29496
|
-
`</pty_spawned>`
|
|
29497
|
-
].join(`
|
|
29498
|
-
`);
|
|
29499
|
-
return output;
|
|
30458
|
+
// src/tools/pty/pty-loader.ts
|
|
30459
|
+
import { existsSync as existsSync4 } from "fs";
|
|
30460
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
30461
|
+
var cachedModule = null;
|
|
30462
|
+
var loadAttempted = false;
|
|
30463
|
+
var loadError = null;
|
|
30464
|
+
function probeBunPtyLib() {
|
|
30465
|
+
if (process.env.BUN_PTY_LIB)
|
|
30466
|
+
return;
|
|
30467
|
+
const platform = process.platform;
|
|
30468
|
+
const arch = process.arch;
|
|
30469
|
+
const filenames = platform === "darwin" ? arch === "arm64" ? ["librust_pty_arm64.dylib", "librust_pty.dylib"] : ["librust_pty.dylib"] : platform === "win32" ? ["rust_pty.dll"] : arch === "arm64" ? ["librust_pty_arm64.so", "librust_pty.so"] : ["librust_pty.so"];
|
|
30470
|
+
const cwd = process.cwd();
|
|
30471
|
+
const additionalBasePaths = [
|
|
30472
|
+
join11(cwd, ".opencode", "node_modules", "bun-pty", "rust-pty", "target", "release"),
|
|
30473
|
+
join11(cwd, ".micode", "node_modules", "bun-pty", "rust-pty", "target", "release")
|
|
30474
|
+
];
|
|
30475
|
+
try {
|
|
30476
|
+
const bunPtyMain = __require.resolve("bun-pty");
|
|
30477
|
+
if (bunPtyMain) {
|
|
30478
|
+
const pkgDir = dirname3(dirname3(bunPtyMain));
|
|
30479
|
+
additionalBasePaths.unshift(join11(pkgDir, "rust-pty", "target", "release"));
|
|
29500
30480
|
}
|
|
29501
|
-
}
|
|
30481
|
+
} catch {}
|
|
30482
|
+
for (const basePath of additionalBasePaths) {
|
|
30483
|
+
for (const filename of filenames) {
|
|
30484
|
+
const candidate = join11(basePath, filename);
|
|
30485
|
+
if (existsSync4(candidate)) {
|
|
30486
|
+
process.env.BUN_PTY_LIB = candidate;
|
|
30487
|
+
log.info("pty.loader", `Auto-resolved BUN_PTY_LIB=${candidate}`);
|
|
30488
|
+
return;
|
|
30489
|
+
}
|
|
30490
|
+
}
|
|
30491
|
+
}
|
|
29502
30492
|
}
|
|
29503
|
-
|
|
29504
|
-
|
|
30493
|
+
async function loadBunPty() {
|
|
30494
|
+
if (loadAttempted)
|
|
30495
|
+
return cachedModule;
|
|
30496
|
+
loadAttempted = true;
|
|
30497
|
+
probeBunPtyLib();
|
|
30498
|
+
try {
|
|
30499
|
+
cachedModule = await import("bun-pty");
|
|
30500
|
+
log.info("pty.loader", "bun-pty loaded successfully");
|
|
30501
|
+
return cachedModule;
|
|
30502
|
+
} catch (error45) {
|
|
30503
|
+
loadError = error45 instanceof Error ? error45.message : String(error45);
|
|
30504
|
+
const firstLine = loadError.split(`
|
|
30505
|
+
`)[0];
|
|
30506
|
+
log.warn("pty.loader", `bun-pty unavailable: ${firstLine}`);
|
|
30507
|
+
log.warn("pty.loader", "PTY tools will be disabled. Set BUN_PTY_LIB env var to the native library path to fix.");
|
|
30508
|
+
cachedModule = null;
|
|
30509
|
+
return null;
|
|
30510
|
+
}
|
|
30511
|
+
}
|
|
30512
|
+
// src/tools/pty/tools/kill.ts
|
|
30513
|
+
var DESCRIPTION = `Terminates a PTY session and optionally cleans up its buffer.
|
|
29505
30514
|
|
|
29506
30515
|
Use this tool to:
|
|
29507
|
-
-
|
|
29508
|
-
-
|
|
29509
|
-
-
|
|
30516
|
+
- Stop a running process (sends SIGTERM)
|
|
30517
|
+
- Clean up an exited session to free memory
|
|
30518
|
+
- Remove a session from the list
|
|
29510
30519
|
|
|
29511
30520
|
Usage:
|
|
29512
30521
|
- \`id\`: The PTY session ID (from pty_spawn or pty_list)
|
|
29513
|
-
- \`
|
|
30522
|
+
- \`cleanup\`: If true, removes the session and frees the buffer (default: false)
|
|
29514
30523
|
|
|
29515
|
-
|
|
29516
|
-
-
|
|
29517
|
-
-
|
|
29518
|
-
-
|
|
29519
|
-
-
|
|
29520
|
-
- Tab: "\\t"
|
|
29521
|
-
- Arrow Up: "\\x1b[A"
|
|
29522
|
-
- Arrow Down: "\\x1b[B"
|
|
29523
|
-
- Arrow Right: "\\x1b[C"
|
|
29524
|
-
- Arrow Left: "\\x1b[D"
|
|
30524
|
+
Behavior:
|
|
30525
|
+
- If the session is running, it will be killed (status becomes "killed")
|
|
30526
|
+
- If cleanup=false (default), the session remains in the list with its output buffer intact
|
|
30527
|
+
- If cleanup=true, the session is removed entirely and the buffer is freed
|
|
30528
|
+
- Keeping sessions without cleanup allows you to compare logs between runs
|
|
29525
30529
|
|
|
29526
|
-
|
|
30530
|
+
Tips:
|
|
30531
|
+
- Use cleanup=false if you might want to read the output later
|
|
30532
|
+
- Use cleanup=true when you're done with the session entirely
|
|
30533
|
+
- To send Ctrl+C instead of killing, use pty_write with data="\\x03"
|
|
29527
30534
|
|
|
29528
30535
|
Examples:
|
|
29529
|
-
-
|
|
29530
|
-
-
|
|
29531
|
-
|
|
29532
|
-
|
|
29533
|
-
|
|
29534
|
-
|
|
29535
|
-
|
|
29536
|
-
|
|
29537
|
-
|
|
29538
|
-
|
|
29539
|
-
|
|
29540
|
-
|
|
29541
|
-
|
|
29542
|
-
|
|
29543
|
-
|
|
29544
|
-
|
|
29545
|
-
|
|
29546
|
-
|
|
29547
|
-
|
|
29548
|
-
|
|
29549
|
-
|
|
29550
|
-
|
|
29551
|
-
|
|
29552
|
-
|
|
29553
|
-
|
|
30536
|
+
- Kill but keep logs: cleanup=false (or omit)
|
|
30537
|
+
- Kill and remove: cleanup=true`;
|
|
30538
|
+
function createPtyKillTool(manager) {
|
|
30539
|
+
return tool({
|
|
30540
|
+
description: DESCRIPTION,
|
|
30541
|
+
args: {
|
|
30542
|
+
id: tool.schema.string().describe("The PTY session ID (e.g., pty_a1b2c3d4)"),
|
|
30543
|
+
cleanup: tool.schema.boolean().optional().describe("If true, removes the session and frees the buffer (default: false)")
|
|
30544
|
+
},
|
|
30545
|
+
execute: async (args) => {
|
|
30546
|
+
const session = manager.get(args.id);
|
|
30547
|
+
if (!session) {
|
|
30548
|
+
throw new Error(`PTY session '${args.id}' not found. Use pty_list to see active sessions.`);
|
|
30549
|
+
}
|
|
30550
|
+
const wasRunning = session.status === "running";
|
|
30551
|
+
const cleanup = args.cleanup ?? false;
|
|
30552
|
+
const success2 = manager.kill(args.id, cleanup);
|
|
30553
|
+
if (!success2) {
|
|
30554
|
+
throw new Error(`Failed to kill PTY session '${args.id}'.`);
|
|
30555
|
+
}
|
|
30556
|
+
const action = wasRunning ? "Killed" : "Cleaned up";
|
|
30557
|
+
const cleanupNote = cleanup ? " (session removed)" : " (session retained for log access)";
|
|
30558
|
+
return [
|
|
30559
|
+
`<pty_killed>`,
|
|
30560
|
+
`${action}: ${args.id}${cleanupNote}`,
|
|
30561
|
+
`Title: ${session.title}`,
|
|
30562
|
+
`Command: ${session.command} ${session.args.join(" ")}`,
|
|
30563
|
+
`Final line count: ${session.lineCount}`,
|
|
30564
|
+
`</pty_killed>`
|
|
30565
|
+
].join(`
|
|
30566
|
+
`);
|
|
29554
30567
|
}
|
|
29555
30568
|
});
|
|
29556
30569
|
}
|
|
29557
|
-
|
|
30570
|
+
// src/tools/pty/tools/list.ts
|
|
30571
|
+
var DESCRIPTION2 = `Lists all PTY sessions (active and exited).
|
|
30572
|
+
|
|
30573
|
+
Use this tool to:
|
|
30574
|
+
- See all running and exited PTY sessions
|
|
30575
|
+
- Get session IDs for use with other pty_* tools
|
|
30576
|
+
- Check the status and output line count of each session
|
|
30577
|
+
- Monitor which processes are still running
|
|
30578
|
+
|
|
30579
|
+
Returns for each session:
|
|
30580
|
+
- \`id\`: Unique identifier for use with other tools
|
|
30581
|
+
- \`title\`: Human-readable name
|
|
30582
|
+
- \`command\`: The command that was executed
|
|
30583
|
+
- \`status\`: Current status (running, exited, killed)
|
|
30584
|
+
- \`exitCode\`: Exit code (if exited/killed)
|
|
30585
|
+
- \`pid\`: Process ID
|
|
30586
|
+
- \`lineCount\`: Number of lines in the output buffer
|
|
30587
|
+
- \`createdAt\`: When the session was created
|
|
30588
|
+
|
|
30589
|
+
Tips:
|
|
30590
|
+
- Use the session ID with pty_read, pty_write, or pty_kill
|
|
30591
|
+
- Sessions remain in the list after exit until explicitly cleaned up with pty_kill
|
|
30592
|
+
- This allows you to compare output from multiple sessions`;
|
|
30593
|
+
function createPtyListTool(manager) {
|
|
29558
30594
|
return tool({
|
|
29559
30595
|
description: DESCRIPTION2,
|
|
29560
|
-
args: {
|
|
29561
|
-
|
|
29562
|
-
|
|
29563
|
-
|
|
29564
|
-
|
|
29565
|
-
|
|
29566
|
-
|
|
29567
|
-
throw new Error(`PTY session '${args.id}' not found. Use pty_list to see active sessions.`);
|
|
29568
|
-
}
|
|
29569
|
-
if (session.status !== "running") {
|
|
29570
|
-
throw new Error(`Cannot write to PTY '${args.id}' - session status is '${session.status}'.`);
|
|
30596
|
+
args: {},
|
|
30597
|
+
execute: async () => {
|
|
30598
|
+
const sessions = manager.list();
|
|
30599
|
+
if (sessions.length === 0) {
|
|
30600
|
+
return `<pty_list>
|
|
30601
|
+
No active PTY sessions.
|
|
30602
|
+
</pty_list>`;
|
|
29571
30603
|
}
|
|
29572
|
-
const
|
|
29573
|
-
const
|
|
29574
|
-
|
|
29575
|
-
|
|
30604
|
+
const lines = ["<pty_list>"];
|
|
30605
|
+
for (const session of sessions) {
|
|
30606
|
+
const exitInfo = session.exitCode !== undefined ? ` (exit: ${session.exitCode})` : "";
|
|
30607
|
+
lines.push(`[${session.id}] ${session.title}`);
|
|
30608
|
+
lines.push(` Command: ${session.command} ${session.args.join(" ")}`);
|
|
30609
|
+
lines.push(` Status: ${session.status}${exitInfo}`);
|
|
30610
|
+
lines.push(` PID: ${session.pid} | Lines: ${session.lineCount} | Workdir: ${session.workdir}`);
|
|
30611
|
+
lines.push(` Created: ${session.createdAt.toISOString()}`);
|
|
30612
|
+
lines.push("");
|
|
29576
30613
|
}
|
|
29577
|
-
|
|
29578
|
-
|
|
29579
|
-
return `
|
|
30614
|
+
lines.push(`Total: ${sessions.length} session(s)`);
|
|
30615
|
+
lines.push("</pty_list>");
|
|
30616
|
+
return lines.join(`
|
|
30617
|
+
`);
|
|
29580
30618
|
}
|
|
29581
30619
|
});
|
|
29582
30620
|
}
|
|
@@ -29710,112 +30748,150 @@ function createPtyReadTool(manager) {
|
|
|
29710
30748
|
}
|
|
29711
30749
|
});
|
|
29712
30750
|
}
|
|
29713
|
-
// src/tools/pty/tools/
|
|
29714
|
-
var DESCRIPTION4 = `
|
|
30751
|
+
// src/tools/pty/tools/spawn.ts
|
|
30752
|
+
var DESCRIPTION4 = `Spawns a new interactive PTY (pseudo-terminal) session that runs in the background.
|
|
29715
30753
|
|
|
29716
|
-
|
|
29717
|
-
-
|
|
29718
|
-
-
|
|
29719
|
-
-
|
|
29720
|
-
-
|
|
30754
|
+
Unlike the built-in bash tool which runs commands synchronously and waits for completion, PTY sessions persist and allow you to:
|
|
30755
|
+
- Run long-running processes (dev servers, watch modes, etc.)
|
|
30756
|
+
- Send interactive input (including Ctrl+C, arrow keys, etc.)
|
|
30757
|
+
- Read output at any time
|
|
30758
|
+
- Manage multiple concurrent terminal sessions
|
|
29721
30759
|
|
|
29722
|
-
|
|
29723
|
-
- \`
|
|
29724
|
-
- \`
|
|
29725
|
-
- \`
|
|
29726
|
-
- \`
|
|
29727
|
-
- \`
|
|
30760
|
+
Usage:
|
|
30761
|
+
- The \`command\` parameter is required (e.g., "npm", "python", "bash")
|
|
30762
|
+
- Use \`args\` to pass arguments to the command (e.g., ["run", "dev"])
|
|
30763
|
+
- Use \`workdir\` to set the working directory (defaults to project root)
|
|
30764
|
+
- Use \`env\` to set additional environment variables
|
|
30765
|
+
- Use \`title\` to give the session a human-readable name
|
|
30766
|
+
- Use \`description\` for a clear, concise 5-10 word description (optional)
|
|
30767
|
+
|
|
30768
|
+
Returns the session info including:
|
|
30769
|
+
- \`id\`: Unique identifier (pty_XXXXXXXX) for use with other pty_* tools
|
|
29728
30770
|
- \`pid\`: Process ID
|
|
29729
|
-
- \`
|
|
29730
|
-
- \`createdAt\`: When the session was created
|
|
30771
|
+
- \`status\`: Current status ("running")
|
|
29731
30772
|
|
|
29732
|
-
|
|
29733
|
-
-
|
|
29734
|
-
-
|
|
29735
|
-
-
|
|
29736
|
-
|
|
30773
|
+
After spawning, use:
|
|
30774
|
+
- \`pty_write\` to send input to the PTY
|
|
30775
|
+
- \`pty_read\` to read output from the PTY
|
|
30776
|
+
- \`pty_list\` to see all active PTY sessions
|
|
30777
|
+
- \`pty_kill\` to terminate the PTY
|
|
30778
|
+
|
|
30779
|
+
Examples:
|
|
30780
|
+
- Start a dev server: command="npm", args=["run", "dev"], title="Dev Server"
|
|
30781
|
+
- Start a Python REPL: command="python3", title="Python REPL"
|
|
30782
|
+
- Run tests in watch mode: command="npm", args=["test", "--", "--watch"]`;
|
|
30783
|
+
function createPtySpawnTool(manager) {
|
|
29737
30784
|
return tool({
|
|
29738
30785
|
description: DESCRIPTION4,
|
|
29739
|
-
args: {
|
|
29740
|
-
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
|
|
29744
|
-
|
|
29745
|
-
|
|
29746
|
-
|
|
29747
|
-
|
|
29748
|
-
|
|
29749
|
-
|
|
29750
|
-
|
|
29751
|
-
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
29759
|
-
|
|
30786
|
+
args: {
|
|
30787
|
+
command: tool.schema.string().describe("The command/executable to run"),
|
|
30788
|
+
args: tool.schema.array(tool.schema.string()).optional().describe("Arguments to pass to the command"),
|
|
30789
|
+
workdir: tool.schema.string().optional().describe("Working directory for the PTY session"),
|
|
30790
|
+
env: tool.schema.record(tool.schema.string(), tool.schema.string()).optional().describe("Additional environment variables"),
|
|
30791
|
+
title: tool.schema.string().optional().describe("Human-readable title for the session"),
|
|
30792
|
+
description: tool.schema.string().optional().describe("Clear, concise description of what this PTY session is for in 5-10 words")
|
|
30793
|
+
},
|
|
30794
|
+
execute: async (args, ctx) => {
|
|
30795
|
+
const info = manager.spawn({
|
|
30796
|
+
command: args.command,
|
|
30797
|
+
args: args.args,
|
|
30798
|
+
workdir: args.workdir,
|
|
30799
|
+
env: args.env,
|
|
30800
|
+
title: args.title,
|
|
30801
|
+
parentSessionId: ctx.sessionID
|
|
30802
|
+
});
|
|
30803
|
+
const output = [
|
|
30804
|
+
`<pty_spawned>`,
|
|
30805
|
+
`ID: ${info.id}`,
|
|
30806
|
+
`Title: ${info.title}`,
|
|
30807
|
+
`Command: ${info.command} ${info.args.join(" ")}`,
|
|
30808
|
+
`Workdir: ${info.workdir}`,
|
|
30809
|
+
`PID: ${info.pid}`,
|
|
30810
|
+
`Status: ${info.status}`,
|
|
30811
|
+
`</pty_spawned>`
|
|
30812
|
+
].join(`
|
|
29760
30813
|
`);
|
|
30814
|
+
return output;
|
|
29761
30815
|
}
|
|
29762
30816
|
});
|
|
29763
30817
|
}
|
|
29764
|
-
// src/tools/pty/tools/
|
|
29765
|
-
var DESCRIPTION5 = `
|
|
30818
|
+
// src/tools/pty/tools/write.ts
|
|
30819
|
+
var DESCRIPTION5 = `Sends input data to an active PTY session.
|
|
29766
30820
|
|
|
29767
30821
|
Use this tool to:
|
|
29768
|
-
-
|
|
29769
|
-
-
|
|
29770
|
-
-
|
|
30822
|
+
- Type commands or text into an interactive terminal
|
|
30823
|
+
- Send special key sequences (Ctrl+C, Enter, arrow keys, etc.)
|
|
30824
|
+
- Respond to prompts in interactive programs
|
|
29771
30825
|
|
|
29772
30826
|
Usage:
|
|
29773
30827
|
- \`id\`: The PTY session ID (from pty_spawn or pty_list)
|
|
29774
|
-
- \`
|
|
30828
|
+
- \`data\`: The input to send (text, commands, or escape sequences)
|
|
29775
30829
|
|
|
29776
|
-
|
|
29777
|
-
-
|
|
29778
|
-
-
|
|
29779
|
-
-
|
|
29780
|
-
-
|
|
30830
|
+
Common escape sequences:
|
|
30831
|
+
- Enter/newline: "\\n" or "\\r"
|
|
30832
|
+
- Ctrl+C (interrupt): "\\x03"
|
|
30833
|
+
- Ctrl+D (EOF): "\\x04"
|
|
30834
|
+
- Ctrl+Z (suspend): "\\x1a"
|
|
30835
|
+
- Tab: "\\t"
|
|
30836
|
+
- Arrow Up: "\\x1b[A"
|
|
30837
|
+
- Arrow Down: "\\x1b[B"
|
|
30838
|
+
- Arrow Right: "\\x1b[C"
|
|
30839
|
+
- Arrow Left: "\\x1b[D"
|
|
29781
30840
|
|
|
29782
|
-
|
|
29783
|
-
- Use cleanup=false if you might want to read the output later
|
|
29784
|
-
- Use cleanup=true when you're done with the session entirely
|
|
29785
|
-
- To send Ctrl+C instead of killing, use pty_write with data="\\x03"
|
|
30841
|
+
Returns success or error message.
|
|
29786
30842
|
|
|
29787
30843
|
Examples:
|
|
29788
|
-
-
|
|
29789
|
-
-
|
|
29790
|
-
|
|
30844
|
+
- Send a command: data="ls -la\\n"
|
|
30845
|
+
- Interrupt a process: data="\\x03"
|
|
30846
|
+
- Answer a prompt: data="yes\\n"`;
|
|
30847
|
+
function parseEscapeSequences(input) {
|
|
30848
|
+
return input.replace(/\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|[nrt0\\])/g, (match, seq) => {
|
|
30849
|
+
if (seq.startsWith("x")) {
|
|
30850
|
+
return String.fromCharCode(parseInt(seq.slice(1), 16));
|
|
30851
|
+
}
|
|
30852
|
+
if (seq.startsWith("u")) {
|
|
30853
|
+
return String.fromCharCode(parseInt(seq.slice(1), 16));
|
|
30854
|
+
}
|
|
30855
|
+
switch (seq) {
|
|
30856
|
+
case "n":
|
|
30857
|
+
return `
|
|
30858
|
+
`;
|
|
30859
|
+
case "r":
|
|
30860
|
+
return "\r";
|
|
30861
|
+
case "t":
|
|
30862
|
+
return "\t";
|
|
30863
|
+
case "0":
|
|
30864
|
+
return "\x00";
|
|
30865
|
+
case "\\":
|
|
30866
|
+
return "\\";
|
|
30867
|
+
default:
|
|
30868
|
+
return match;
|
|
30869
|
+
}
|
|
30870
|
+
});
|
|
30871
|
+
}
|
|
30872
|
+
function createPtyWriteTool(manager) {
|
|
29791
30873
|
return tool({
|
|
29792
30874
|
description: DESCRIPTION5,
|
|
29793
30875
|
args: {
|
|
29794
30876
|
id: tool.schema.string().describe("The PTY session ID (e.g., pty_a1b2c3d4)"),
|
|
29795
|
-
|
|
30877
|
+
data: tool.schema.string().describe("The input data to send to the PTY")
|
|
29796
30878
|
},
|
|
29797
30879
|
execute: async (args) => {
|
|
29798
30880
|
const session = manager.get(args.id);
|
|
29799
30881
|
if (!session) {
|
|
29800
30882
|
throw new Error(`PTY session '${args.id}' not found. Use pty_list to see active sessions.`);
|
|
29801
30883
|
}
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
|
|
30884
|
+
if (session.status !== "running") {
|
|
30885
|
+
throw new Error(`Cannot write to PTY '${args.id}' - session status is '${session.status}'.`);
|
|
30886
|
+
}
|
|
30887
|
+
const parsedData = parseEscapeSequences(args.data);
|
|
30888
|
+
const success2 = manager.write(args.id, parsedData);
|
|
29805
30889
|
if (!success2) {
|
|
29806
|
-
throw new Error(`Failed to
|
|
30890
|
+
throw new Error(`Failed to write to PTY '${args.id}'.`);
|
|
29807
30891
|
}
|
|
29808
|
-
const
|
|
29809
|
-
const
|
|
29810
|
-
return
|
|
29811
|
-
`<pty_killed>`,
|
|
29812
|
-
`${action}: ${args.id}${cleanupNote}`,
|
|
29813
|
-
`Title: ${session.title}`,
|
|
29814
|
-
`Command: ${session.command} ${session.args.join(" ")}`,
|
|
29815
|
-
`Final line count: ${session.lineCount}`,
|
|
29816
|
-
`</pty_killed>`
|
|
29817
|
-
].join(`
|
|
29818
|
-
`);
|
|
30892
|
+
const preview = args.data.length > 50 ? `${args.data.slice(0, 50)}...` : args.data;
|
|
30893
|
+
const displayPreview = preview.replace(/\x03/g, "^C").replace(/\x04/g, "^D").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
30894
|
+
return `Sent ${parsedData.length} bytes to ${args.id}: "${displayPreview}"`;
|
|
29819
30895
|
}
|
|
29820
30896
|
});
|
|
29821
30897
|
}
|
|
@@ -30004,6 +31080,7 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30004
31080
|
const commentCheckerHook = createCommentCheckerHook(ctx);
|
|
30005
31081
|
const artifactAutoIndexHook = createArtifactAutoIndexHook(ctx);
|
|
30006
31082
|
const fileOpsTrackerHook = createFileOpsTrackerHook(ctx);
|
|
31083
|
+
const fetchTrackerHook = createFetchTrackerHook(ctx);
|
|
30007
31084
|
const fragmentInjectorHook = createFragmentInjectorHook(ctx, userConfig);
|
|
30008
31085
|
if (userConfig?.fragments) {
|
|
30009
31086
|
const knownAgentNames = new Set(Object.keys(agents));
|
|
@@ -30057,7 +31134,11 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30057
31134
|
}
|
|
30058
31135
|
});
|
|
30059
31136
|
const ptyManager = new PTYManager;
|
|
30060
|
-
const
|
|
31137
|
+
const bunPty = await loadBunPty();
|
|
31138
|
+
if (bunPty) {
|
|
31139
|
+
ptyManager.init(bunPty.spawn);
|
|
31140
|
+
}
|
|
31141
|
+
const ptyTools = ptyManager.available ? createPtyTools(ptyManager) : {};
|
|
30061
31142
|
const spawn_agent = createSpawnAgentTool(ctx);
|
|
30062
31143
|
const batch_read = createBatchReadTool(ctx);
|
|
30063
31144
|
const octtoSessionStore = createSessionStore();
|
|
@@ -30098,7 +31179,6 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30098
31179
|
edit: "allow",
|
|
30099
31180
|
bash: "allow",
|
|
30100
31181
|
webfetch: "allow",
|
|
30101
|
-
doom_loop: "allow",
|
|
30102
31182
|
external_directory: "allow"
|
|
30103
31183
|
};
|
|
30104
31184
|
const mergedAgents = mergeAgentConfigs(agents, userConfig);
|
|
@@ -30154,7 +31234,7 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30154
31234
|
...output.options,
|
|
30155
31235
|
thinking: {
|
|
30156
31236
|
type: "enabled",
|
|
30157
|
-
|
|
31237
|
+
budgetTokens: 128000
|
|
30158
31238
|
}
|
|
30159
31239
|
};
|
|
30160
31240
|
}
|
|
@@ -30215,6 +31295,7 @@ IMPORTANT:
|
|
|
30215
31295
|
await contextInjectorHook["tool.execute.after"]({ tool: input.tool, args: input.args }, output);
|
|
30216
31296
|
await artifactAutoIndexHook["tool.execute.after"]({ tool: input.tool, args: input.args }, output);
|
|
30217
31297
|
await fileOpsTrackerHook["tool.execute.after"]({ tool: input.tool, sessionID: input.sessionID, args: input.args }, output);
|
|
31298
|
+
await fetchTrackerHook["tool.execute.after"]({ tool: input.tool, sessionID: input.sessionID, args: input.args }, output);
|
|
30218
31299
|
await constraintReviewerHook["tool.execute.after"]({ tool: input.tool, sessionID: input.sessionID, args: input.args }, output);
|
|
30219
31300
|
},
|
|
30220
31301
|
"experimental.chat.messages.transform": async (input, output) => {
|
|
@@ -30248,6 +31329,7 @@ IMPORTANT:
|
|
|
30248
31329
|
thinkModeState.delete(sessionId);
|
|
30249
31330
|
ptyManager.cleanupBySession(sessionId);
|
|
30250
31331
|
constraintReviewerHook.cleanupSession(sessionId);
|
|
31332
|
+
fetchTrackerHook.cleanupSession(sessionId);
|
|
30251
31333
|
const octtoSessions = octtoSessionsMap.get(sessionId);
|
|
30252
31334
|
if (octtoSessions) {
|
|
30253
31335
|
for (const octtoSessionId of octtoSessions) {
|
|
@@ -30262,6 +31344,7 @@ IMPORTANT:
|
|
|
30262
31344
|
await tokenAwareTruncationHook.event({ event });
|
|
30263
31345
|
await contextWindowMonitorHook.event({ event });
|
|
30264
31346
|
await fileOpsTrackerHook.event({ event });
|
|
31347
|
+
await fetchTrackerHook.event({ event });
|
|
30265
31348
|
}
|
|
30266
31349
|
};
|
|
30267
31350
|
};
|