micode 0.9.0 → 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 +1614 -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 +78 -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,1062 @@ 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
|
-
const { model: _ignored, ...safeOverrides } = userOverride;
|
|
10642
|
-
finalConfig = { ...finalConfig, ...safeOverrides };
|
|
10732
|
+
scanError = 6;
|
|
10643
10733
|
}
|
|
10644
|
-
} else {
|
|
10645
|
-
finalConfig = { ...finalConfig, ...userOverride };
|
|
10646
10734
|
}
|
|
10735
|
+
pos++;
|
|
10647
10736
|
}
|
|
10648
|
-
|
|
10737
|
+
return result;
|
|
10649
10738
|
}
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
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
|
+
}
|
|
10669
10875
|
}
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
mkdirSync(dir, { recursive: true });
|
|
10876
|
+
function isUnknownContentCharacter(code) {
|
|
10877
|
+
if (isWhiteSpace(code) || isLineBreak(code)) {
|
|
10878
|
+
return false;
|
|
10674
10879
|
}
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
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;
|
|
10682
10890
|
}
|
|
10683
|
-
|
|
10891
|
+
return true;
|
|
10684
10892
|
}
|
|
10685
|
-
|
|
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,
|
|
11612
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
10694
11613
|
indexed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
10695
11614
|
);
|
|
10696
11615
|
CREATE TABLE IF NOT EXISTS ledgers (
|
|
@@ -11025,79 +11944,16 @@ function createArtifactAutoIndexHook(_ctx) {
|
|
|
11025
11944
|
await index.indexPlan(record);
|
|
11026
11945
|
return;
|
|
11027
11946
|
}
|
|
11028
|
-
} catch (e) {
|
|
11029
|
-
log.error("artifact-auto-index", `Error indexing ${filePath}`, e);
|
|
11030
|
-
}
|
|
11031
|
-
}
|
|
11032
|
-
};
|
|
11033
|
-
}
|
|
11034
|
-
|
|
11035
|
-
// src/hooks/auto-compact.ts
|
|
11036
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
11037
|
-
import { join as join3 } from "path";
|
|
11038
|
-
|
|
11039
|
-
// src/utils/config.ts
|
|
11040
|
-
var config = {
|
|
11041
|
-
compaction: {
|
|
11042
|
-
threshold: 0.7,
|
|
11043
|
-
cooldownMs: 120000,
|
|
11044
|
-
timeoutMs: 120000
|
|
11045
|
-
},
|
|
11046
|
-
contextWindow: {
|
|
11047
|
-
warningThreshold: 0.7,
|
|
11048
|
-
criticalThreshold: 0.85,
|
|
11049
|
-
warningCooldownMs: 120000
|
|
11050
|
-
},
|
|
11051
|
-
tokens: {
|
|
11052
|
-
charsPerToken: 4,
|
|
11053
|
-
defaultContextLimit: 200000,
|
|
11054
|
-
defaultMaxOutputTokens: 50000,
|
|
11055
|
-
safetyMargin: 0.5,
|
|
11056
|
-
preserveHeaderLines: 3
|
|
11057
|
-
},
|
|
11058
|
-
paths: {
|
|
11059
|
-
ledgerDir: "thoughts/ledgers",
|
|
11060
|
-
ledgerPrefix: "CONTINUITY_",
|
|
11061
|
-
rootContextFiles: ["README.md", "ARCHITECTURE.md", "CODE_STYLE.md"],
|
|
11062
|
-
dirContextFiles: ["README.md"],
|
|
11063
|
-
planPattern: /thoughts\/shared\/plans\/.*\.md$/,
|
|
11064
|
-
ledgerPattern: /thoughts\/ledgers\/CONTINUITY_.*\.md$/,
|
|
11065
|
-
mindmodelDir: ".mindmodel",
|
|
11066
|
-
mindmodelManifest: "manifest.yaml",
|
|
11067
|
-
mindmodelSystem: "system.md"
|
|
11068
|
-
},
|
|
11069
|
-
timeouts: {
|
|
11070
|
-
btcaMs: 120000,
|
|
11071
|
-
toastSuccessMs: 3000,
|
|
11072
|
-
toastWarningMs: 4000,
|
|
11073
|
-
toastErrorMs: 5000
|
|
11074
|
-
},
|
|
11075
|
-
limits: {
|
|
11076
|
-
largeFileBytes: 100 * 1024,
|
|
11077
|
-
maxLinesNoExtract: 200,
|
|
11078
|
-
ptyMaxBufferLines: 50000,
|
|
11079
|
-
ptyDefaultReadLimit: 500,
|
|
11080
|
-
ptyMaxLineLength: 2000,
|
|
11081
|
-
astGrepMaxMatches: 100,
|
|
11082
|
-
contextCacheTtlMs: 30000,
|
|
11083
|
-
contextCacheMaxSize: 100
|
|
11084
|
-
},
|
|
11085
|
-
octto: {
|
|
11086
|
-
answerTimeoutMs: 5 * 60 * 1000,
|
|
11087
|
-
reviewTimeoutMs: 10 * 60 * 1000,
|
|
11088
|
-
maxIterations: 50,
|
|
11089
|
-
maxQuestions: 15,
|
|
11090
|
-
stateDir: "thoughts/brainstorms",
|
|
11091
|
-
bindAddress: "127.0.0.1",
|
|
11092
|
-
allowRemoteBind: false
|
|
11093
|
-
},
|
|
11094
|
-
mindmodel: {
|
|
11095
|
-
overrideLogFile: "overrides.log",
|
|
11096
|
-
reviewMaxRetries: 1,
|
|
11097
|
-
reviewEnabled: true,
|
|
11098
|
-
categoryGroups: ["stack", "architecture", "patterns", "style", "components", "domain", "ops"]
|
|
11099
|
-
}
|
|
11100
|
-
};
|
|
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";
|
|
11101
11957
|
|
|
11102
11958
|
// src/utils/errors.ts
|
|
11103
11959
|
function extractErrorMessage(e) {
|
|
@@ -11719,7 +12575,7 @@ function string(message$1) {
|
|
|
11719
12575
|
}
|
|
11720
12576
|
};
|
|
11721
12577
|
}
|
|
11722
|
-
function
|
|
12578
|
+
function parse3(schema, input, config$1) {
|
|
11723
12579
|
const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1));
|
|
11724
12580
|
if (dataset.issues)
|
|
11725
12581
|
throw new ValiError(dataset.issues);
|
|
@@ -11763,7 +12619,7 @@ var lexer = require_lexer();
|
|
|
11763
12619
|
var lineCounter = require_line_counter();
|
|
11764
12620
|
var parser = require_parser();
|
|
11765
12621
|
var publicApi = require_public_api();
|
|
11766
|
-
var
|
|
12622
|
+
var visit2 = require_visit();
|
|
11767
12623
|
var $Composer = composer.Composer;
|
|
11768
12624
|
var $Document = Document.Document;
|
|
11769
12625
|
var $Schema = Schema.Schema;
|
|
@@ -11790,8 +12646,8 @@ var $parse = publicApi.parse;
|
|
|
11790
12646
|
var $parseAllDocuments = publicApi.parseAllDocuments;
|
|
11791
12647
|
var $parseDocument = publicApi.parseDocument;
|
|
11792
12648
|
var $stringify = publicApi.stringify;
|
|
11793
|
-
var $visit =
|
|
11794
|
-
var $visitAsync =
|
|
12649
|
+
var $visit = visit2.visit;
|
|
12650
|
+
var $visitAsync = visit2.visitAsync;
|
|
11795
12651
|
|
|
11796
12652
|
// src/mindmodel/types.ts
|
|
11797
12653
|
var CategorySchema = object({
|
|
@@ -11806,7 +12662,7 @@ var ManifestSchema = object({
|
|
|
11806
12662
|
});
|
|
11807
12663
|
function parseManifest(yamlContent) {
|
|
11808
12664
|
const parsed = $parse(yamlContent);
|
|
11809
|
-
return
|
|
12665
|
+
return parse3(ManifestSchema, parsed);
|
|
11810
12666
|
}
|
|
11811
12667
|
|
|
11812
12668
|
// src/mindmodel/loader.ts
|
|
@@ -11826,7 +12682,7 @@ async function loadMindmodel(projectDir) {
|
|
|
11826
12682
|
manifest
|
|
11827
12683
|
};
|
|
11828
12684
|
} catch (error) {
|
|
11829
|
-
|
|
12685
|
+
log.warn("mindmodel", `Failed to load manifest: ${error}`);
|
|
11830
12686
|
return null;
|
|
11831
12687
|
}
|
|
11832
12688
|
}
|
|
@@ -11845,7 +12701,7 @@ async function loadExamples(mindmodel, categoryPaths) {
|
|
|
11845
12701
|
content
|
|
11846
12702
|
});
|
|
11847
12703
|
} catch {
|
|
11848
|
-
|
|
12704
|
+
log.warn("mindmodel", `Failed to load example: ${categoryPath}`);
|
|
11849
12705
|
}
|
|
11850
12706
|
}
|
|
11851
12707
|
return examples;
|
|
@@ -12204,6 +13060,165 @@ function createContextWindowMonitorHook(ctx, hookConfig) {
|
|
|
12204
13060
|
};
|
|
12205
13061
|
}
|
|
12206
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
|
+
|
|
12207
13222
|
// src/hooks/file-ops-tracker.ts
|
|
12208
13223
|
var sessionFileOps = new Map;
|
|
12209
13224
|
function getOrCreateOps(sessionID) {
|
|
@@ -12494,7 +13509,7 @@ __export(exports_external, {
|
|
|
12494
13509
|
pipe: () => pipe2,
|
|
12495
13510
|
partialRecord: () => partialRecord,
|
|
12496
13511
|
parseAsync: () => parseAsync2,
|
|
12497
|
-
parse: () =>
|
|
13512
|
+
parse: () => parse6,
|
|
12498
13513
|
overwrite: () => _overwrite,
|
|
12499
13514
|
optional: () => optional2,
|
|
12500
13515
|
object: () => object2,
|
|
@@ -12684,7 +13699,7 @@ __export(exports_core2, {
|
|
|
12684
13699
|
regexes: () => exports_regexes,
|
|
12685
13700
|
prettifyError: () => prettifyError,
|
|
12686
13701
|
parseAsync: () => parseAsync,
|
|
12687
|
-
parse: () =>
|
|
13702
|
+
parse: () => parse4,
|
|
12688
13703
|
locales: () => exports_locales,
|
|
12689
13704
|
isValidJWT: () => isValidJWT,
|
|
12690
13705
|
isValidBase64URL: () => isValidBase64URL,
|
|
@@ -13783,7 +14798,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
13783
14798
|
}
|
|
13784
14799
|
return result.value;
|
|
13785
14800
|
};
|
|
13786
|
-
var
|
|
14801
|
+
var parse4 = /* @__PURE__ */ _parse($ZodRealError);
|
|
13787
14802
|
var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
13788
14803
|
const ctx = _ctx ? Object.assign(_ctx, { async: true }) : { async: true };
|
|
13789
14804
|
let result = schema._zod.run({ value, issues: [] }, ctx);
|
|
@@ -16301,10 +17316,10 @@ var $ZodFunction = /* @__PURE__ */ $constructor("$ZodFunction", (inst, def) => {
|
|
|
16301
17316
|
throw new Error("implement() must be called with a function");
|
|
16302
17317
|
}
|
|
16303
17318
|
return function(...args) {
|
|
16304
|
-
const parsedArgs = inst._def.input ?
|
|
17319
|
+
const parsedArgs = inst._def.input ? parse4(inst._def.input, args) : args;
|
|
16305
17320
|
const result = Reflect.apply(func, this, parsedArgs);
|
|
16306
17321
|
if (inst._def.output) {
|
|
16307
|
-
return
|
|
17322
|
+
return parse4(inst._def.output, result);
|
|
16308
17323
|
}
|
|
16309
17324
|
return result;
|
|
16310
17325
|
};
|
|
@@ -22813,13 +23828,13 @@ function _stringbool(Classes, _params) {
|
|
|
22813
23828
|
});
|
|
22814
23829
|
return codec;
|
|
22815
23830
|
}
|
|
22816
|
-
function _stringFormat(Class2,
|
|
23831
|
+
function _stringFormat(Class2, format2, fnOrRegex, _params = {}) {
|
|
22817
23832
|
const params = normalizeParams(_params);
|
|
22818
23833
|
const def = {
|
|
22819
23834
|
...normalizeParams(_params),
|
|
22820
23835
|
check: "string_format",
|
|
22821
23836
|
type: "string",
|
|
22822
|
-
format,
|
|
23837
|
+
format: format2,
|
|
22823
23838
|
fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
|
|
22824
23839
|
...params
|
|
22825
23840
|
};
|
|
@@ -22881,13 +23896,13 @@ class JSONSchemaGenerator {
|
|
|
22881
23896
|
case "string": {
|
|
22882
23897
|
const json = _json;
|
|
22883
23898
|
json.type = "string";
|
|
22884
|
-
const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
|
|
23899
|
+
const { minimum, maximum, format: format2, patterns, contentEncoding } = schema._zod.bag;
|
|
22885
23900
|
if (typeof minimum === "number")
|
|
22886
23901
|
json.minLength = minimum;
|
|
22887
23902
|
if (typeof maximum === "number")
|
|
22888
23903
|
json.maxLength = maximum;
|
|
22889
|
-
if (
|
|
22890
|
-
json.format = formatMap[
|
|
23904
|
+
if (format2) {
|
|
23905
|
+
json.format = formatMap[format2] ?? format2;
|
|
22891
23906
|
if (json.format === "")
|
|
22892
23907
|
delete json.format;
|
|
22893
23908
|
}
|
|
@@ -22910,8 +23925,8 @@ class JSONSchemaGenerator {
|
|
|
22910
23925
|
}
|
|
22911
23926
|
case "number": {
|
|
22912
23927
|
const json = _json;
|
|
22913
|
-
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
22914
|
-
if (typeof
|
|
23928
|
+
const { minimum, maximum, format: format2, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
23929
|
+
if (typeof format2 === "string" && format2.includes("int"))
|
|
22915
23930
|
json.type = "integer";
|
|
22916
23931
|
else
|
|
22917
23932
|
json.type = "number";
|
|
@@ -23712,7 +24727,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
|
|
|
23712
24727
|
});
|
|
23713
24728
|
|
|
23714
24729
|
// node_modules/zod/v4/classic/parse.js
|
|
23715
|
-
var
|
|
24730
|
+
var parse6 = /* @__PURE__ */ _parse(ZodRealError);
|
|
23716
24731
|
var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
23717
24732
|
var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
23718
24733
|
var safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
@@ -23746,7 +24761,7 @@ var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
|
|
|
23746
24761
|
reg.add(inst, meta);
|
|
23747
24762
|
return inst;
|
|
23748
24763
|
};
|
|
23749
|
-
inst.parse = (data, params) =>
|
|
24764
|
+
inst.parse = (data, params) => parse6(inst, data, params, { callee: inst.parse });
|
|
23750
24765
|
inst.safeParse = (data, params) => safeParse2(inst, data, params);
|
|
23751
24766
|
inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
|
|
23752
24767
|
inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params);
|
|
@@ -24011,8 +25026,8 @@ var ZodCustomStringFormat = /* @__PURE__ */ $constructor("ZodCustomStringFormat"
|
|
|
24011
25026
|
$ZodCustomStringFormat.init(inst, def);
|
|
24012
25027
|
ZodStringFormat.init(inst, def);
|
|
24013
25028
|
});
|
|
24014
|
-
function stringFormat(
|
|
24015
|
-
return _stringFormat(ZodCustomStringFormat,
|
|
25029
|
+
function stringFormat(format2, fnOrRegex, _params = {}) {
|
|
25030
|
+
return _stringFormat(ZodCustomStringFormat, format2, fnOrRegex, _params);
|
|
24016
25031
|
}
|
|
24017
25032
|
function hostname2(_params) {
|
|
24018
25033
|
return _stringFormat(ZodCustomStringFormat, "hostname", exports_regexes.hostname, _params);
|
|
@@ -24022,11 +25037,11 @@ function hex2(_params) {
|
|
|
24022
25037
|
}
|
|
24023
25038
|
function hash(alg, params) {
|
|
24024
25039
|
const enc = params?.enc ?? "hex";
|
|
24025
|
-
const
|
|
24026
|
-
const regex = exports_regexes[
|
|
25040
|
+
const format2 = `${alg}_${enc}`;
|
|
25041
|
+
const regex = exports_regexes[format2];
|
|
24027
25042
|
if (!regex)
|
|
24028
|
-
throw new Error(`Unrecognized hash format: ${
|
|
24029
|
-
return _stringFormat(ZodCustomStringFormat,
|
|
25043
|
+
throw new Error(`Unrecognized hash format: ${format2}`);
|
|
25044
|
+
return _stringFormat(ZodCustomStringFormat, format2, regex, params);
|
|
24030
25045
|
}
|
|
24031
25046
|
var ZodNumber = /* @__PURE__ */ $constructor("ZodNumber", (inst, def) => {
|
|
24032
25047
|
$ZodNumber.init(inst, def);
|
|
@@ -24801,13 +25816,13 @@ Returns relevant code examples and patterns to follow.`,
|
|
|
24801
25816
|
if (categories.length === 0) {
|
|
24802
25817
|
return "No specific patterns found for this task. Proceed using general best practices.";
|
|
24803
25818
|
}
|
|
24804
|
-
log.
|
|
25819
|
+
log.debug("mindmodel", `Matched categories: ${categories.join(", ")}`);
|
|
24805
25820
|
const examples = await loadExamples(mindmodel, categories);
|
|
24806
25821
|
if (examples.length === 0) {
|
|
24807
25822
|
return "Categories matched but no examples found. Proceed using general best practices.";
|
|
24808
25823
|
}
|
|
24809
25824
|
const formatted = formatExamplesForInjection(examples);
|
|
24810
|
-
log.
|
|
25825
|
+
log.debug("mindmodel", `Returning ${examples.length} examples`);
|
|
24811
25826
|
return formatted;
|
|
24812
25827
|
} catch (error45) {
|
|
24813
25828
|
log.warn("mindmodel", `Lookup failed: ${error45 instanceof Error ? error45.message : "unknown"}`);
|
|
@@ -24829,7 +25844,7 @@ function hashTask(task) {
|
|
|
24829
25844
|
return hash2.toString(36);
|
|
24830
25845
|
}
|
|
24831
25846
|
|
|
24832
|
-
class
|
|
25847
|
+
class LRUCache2 {
|
|
24833
25848
|
maxSize;
|
|
24834
25849
|
cache = new Map;
|
|
24835
25850
|
constructor(maxSize) {
|
|
@@ -24861,7 +25876,7 @@ function createMindmodelInjectorHook(ctx) {
|
|
|
24861
25876
|
let cachedMindmodel2;
|
|
24862
25877
|
let cachedSystemMd;
|
|
24863
25878
|
let pendingInjection = null;
|
|
24864
|
-
const matchedTasks = new
|
|
25879
|
+
const matchedTasks = new LRUCache2(2000);
|
|
24865
25880
|
async function getMindmodel2() {
|
|
24866
25881
|
if (cachedMindmodel2 === undefined) {
|
|
24867
25882
|
cachedMindmodel2 = await loadMindmodel(ctx.directory);
|
|
@@ -27956,7 +28971,7 @@ function createSessionStore(options = {}) {
|
|
|
27956
28971
|
return store;
|
|
27957
28972
|
}
|
|
27958
28973
|
// src/octto/state/persistence.ts
|
|
27959
|
-
import { existsSync as
|
|
28974
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, rmSync } from "fs";
|
|
27960
28975
|
import { join as join10 } from "path";
|
|
27961
28976
|
function validateSessionId(sessionId) {
|
|
27962
28977
|
if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) {
|
|
@@ -27969,7 +28984,7 @@ function createStatePersistence(baseDir = STATE_DIR) {
|
|
|
27969
28984
|
return join10(baseDir, `${sessionId}.json`);
|
|
27970
28985
|
}
|
|
27971
28986
|
function ensureDir() {
|
|
27972
|
-
if (!
|
|
28987
|
+
if (!existsSync3(baseDir)) {
|
|
27973
28988
|
mkdirSync2(baseDir, { recursive: true });
|
|
27974
28989
|
}
|
|
27975
28990
|
}
|
|
@@ -27982,7 +28997,7 @@ function createStatePersistence(baseDir = STATE_DIR) {
|
|
|
27982
28997
|
},
|
|
27983
28998
|
async load(sessionId) {
|
|
27984
28999
|
const filePath = getFilePath(sessionId);
|
|
27985
|
-
if (!
|
|
29000
|
+
if (!existsSync3(filePath)) {
|
|
27986
29001
|
return null;
|
|
27987
29002
|
}
|
|
27988
29003
|
const content = await Bun.file(filePath).text();
|
|
@@ -27990,12 +29005,12 @@ function createStatePersistence(baseDir = STATE_DIR) {
|
|
|
27990
29005
|
},
|
|
27991
29006
|
async delete(sessionId) {
|
|
27992
29007
|
const filePath = getFilePath(sessionId);
|
|
27993
|
-
if (
|
|
29008
|
+
if (existsSync3(filePath)) {
|
|
27994
29009
|
rmSync(filePath);
|
|
27995
29010
|
}
|
|
27996
29011
|
},
|
|
27997
29012
|
async list() {
|
|
27998
|
-
if (!
|
|
29013
|
+
if (!existsSync3(baseDir)) {
|
|
27999
29014
|
return [];
|
|
28000
29015
|
}
|
|
28001
29016
|
const files = readdirSync(baseDir);
|
|
@@ -29248,9 +30263,6 @@ function createOcttoTools(sessions, client, tracker) {
|
|
|
29248
30263
|
};
|
|
29249
30264
|
}
|
|
29250
30265
|
|
|
29251
|
-
// src/tools/pty/manager.ts
|
|
29252
|
-
import { spawn as spawn3 } from "bun-pty";
|
|
29253
|
-
|
|
29254
30266
|
// src/tools/pty/buffer.ts
|
|
29255
30267
|
var parsed = parseInt(process.env.PTY_MAX_BUFFER_LINES || "50000", 10);
|
|
29256
30268
|
var DEFAULT_MAX_LINES = isNaN(parsed) ? 50000 : parsed;
|
|
@@ -29293,7 +30305,6 @@ class RingBuffer {
|
|
|
29293
30305
|
this.lines = [];
|
|
29294
30306
|
}
|
|
29295
30307
|
}
|
|
29296
|
-
|
|
29297
30308
|
// src/tools/pty/manager.ts
|
|
29298
30309
|
function generateId2() {
|
|
29299
30310
|
const hex3 = Array.from(crypto.getRandomValues(new Uint8Array(4))).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
@@ -29302,7 +30313,19 @@ function generateId2() {
|
|
|
29302
30313
|
|
|
29303
30314
|
class PTYManager {
|
|
29304
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
|
+
}
|
|
29305
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
|
+
}
|
|
29306
30329
|
const id = generateId2();
|
|
29307
30330
|
const args = opts.args ?? [];
|
|
29308
30331
|
const workdir = opts.workdir ?? process.cwd();
|
|
@@ -29310,7 +30333,7 @@ class PTYManager {
|
|
|
29310
30333
|
const title = opts.title ?? (`${opts.command} ${args.join(" ")}`.trim() || `Terminal ${id.slice(-4)}`);
|
|
29311
30334
|
let ptyProcess;
|
|
29312
30335
|
try {
|
|
29313
|
-
ptyProcess =
|
|
30336
|
+
ptyProcess = this.spawnFn(opts.command, args, {
|
|
29314
30337
|
name: "xterm-256color",
|
|
29315
30338
|
cols: 120,
|
|
29316
30339
|
rows: 40,
|
|
@@ -29432,150 +30455,166 @@ class PTYManager {
|
|
|
29432
30455
|
};
|
|
29433
30456
|
}
|
|
29434
30457
|
}
|
|
29435
|
-
// src/tools/pty/
|
|
29436
|
-
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29440
|
-
|
|
29441
|
-
|
|
29442
|
-
|
|
29443
|
-
|
|
29444
|
-
|
|
29445
|
-
|
|
29446
|
-
|
|
29447
|
-
|
|
29448
|
-
|
|
29449
|
-
|
|
29450
|
-
|
|
29451
|
-
|
|
29452
|
-
|
|
29453
|
-
|
|
29454
|
-
|
|
29455
|
-
|
|
29456
|
-
|
|
29457
|
-
After spawning, use:
|
|
29458
|
-
- \`pty_write\` to send input to the PTY
|
|
29459
|
-
- \`pty_read\` to read output from the PTY
|
|
29460
|
-
- \`pty_list\` to see all active PTY sessions
|
|
29461
|
-
- \`pty_kill\` to terminate the PTY
|
|
29462
|
-
|
|
29463
|
-
Examples:
|
|
29464
|
-
- Start a dev server: command="npm", args=["run", "dev"], title="Dev Server"
|
|
29465
|
-
- Start a Python REPL: command="python3", title="Python REPL"
|
|
29466
|
-
- Run tests in watch mode: command="npm", args=["test", "--", "--watch"]`;
|
|
29467
|
-
function createPtySpawnTool(manager) {
|
|
29468
|
-
return tool({
|
|
29469
|
-
description: DESCRIPTION,
|
|
29470
|
-
args: {
|
|
29471
|
-
command: tool.schema.string().describe("The command/executable to run"),
|
|
29472
|
-
args: tool.schema.array(tool.schema.string()).optional().describe("Arguments to pass to the command"),
|
|
29473
|
-
workdir: tool.schema.string().optional().describe("Working directory for the PTY session"),
|
|
29474
|
-
env: tool.schema.record(tool.schema.string(), tool.schema.string()).optional().describe("Additional environment variables"),
|
|
29475
|
-
title: tool.schema.string().optional().describe("Human-readable title for the session"),
|
|
29476
|
-
description: tool.schema.string().optional().describe("Clear, concise description of what this PTY session is for in 5-10 words")
|
|
29477
|
-
},
|
|
29478
|
-
execute: async (args, ctx) => {
|
|
29479
|
-
const info = manager.spawn({
|
|
29480
|
-
command: args.command,
|
|
29481
|
-
args: args.args,
|
|
29482
|
-
workdir: args.workdir,
|
|
29483
|
-
env: args.env,
|
|
29484
|
-
title: args.title,
|
|
29485
|
-
parentSessionId: ctx.sessionID
|
|
29486
|
-
});
|
|
29487
|
-
const output = [
|
|
29488
|
-
`<pty_spawned>`,
|
|
29489
|
-
`ID: ${info.id}`,
|
|
29490
|
-
`Title: ${info.title}`,
|
|
29491
|
-
`Command: ${info.command} ${info.args.join(" ")}`,
|
|
29492
|
-
`Workdir: ${info.workdir}`,
|
|
29493
|
-
`PID: ${info.pid}`,
|
|
29494
|
-
`Status: ${info.status}`,
|
|
29495
|
-
`</pty_spawned>`
|
|
29496
|
-
].join(`
|
|
29497
|
-
`);
|
|
29498
|
-
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"));
|
|
29499
30480
|
}
|
|
29500
|
-
}
|
|
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
|
+
}
|
|
29501
30492
|
}
|
|
29502
|
-
|
|
29503
|
-
|
|
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.
|
|
29504
30514
|
|
|
29505
30515
|
Use this tool to:
|
|
29506
|
-
-
|
|
29507
|
-
-
|
|
29508
|
-
-
|
|
30516
|
+
- Stop a running process (sends SIGTERM)
|
|
30517
|
+
- Clean up an exited session to free memory
|
|
30518
|
+
- Remove a session from the list
|
|
29509
30519
|
|
|
29510
30520
|
Usage:
|
|
29511
30521
|
- \`id\`: The PTY session ID (from pty_spawn or pty_list)
|
|
29512
|
-
- \`
|
|
30522
|
+
- \`cleanup\`: If true, removes the session and frees the buffer (default: false)
|
|
29513
30523
|
|
|
29514
|
-
|
|
29515
|
-
-
|
|
29516
|
-
-
|
|
29517
|
-
-
|
|
29518
|
-
-
|
|
29519
|
-
- Tab: "\\t"
|
|
29520
|
-
- Arrow Up: "\\x1b[A"
|
|
29521
|
-
- Arrow Down: "\\x1b[B"
|
|
29522
|
-
- Arrow Right: "\\x1b[C"
|
|
29523
|
-
- 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
|
|
29524
30529
|
|
|
29525
|
-
|
|
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"
|
|
29526
30534
|
|
|
29527
30535
|
Examples:
|
|
29528
|
-
-
|
|
29529
|
-
-
|
|
29530
|
-
|
|
29531
|
-
|
|
29532
|
-
|
|
29533
|
-
|
|
29534
|
-
|
|
29535
|
-
|
|
29536
|
-
|
|
29537
|
-
|
|
29538
|
-
|
|
29539
|
-
|
|
29540
|
-
|
|
29541
|
-
|
|
29542
|
-
|
|
29543
|
-
|
|
29544
|
-
|
|
29545
|
-
|
|
29546
|
-
|
|
29547
|
-
|
|
29548
|
-
|
|
29549
|
-
|
|
29550
|
-
|
|
29551
|
-
|
|
29552
|
-
|
|
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
|
+
`);
|
|
29553
30567
|
}
|
|
29554
30568
|
});
|
|
29555
30569
|
}
|
|
29556
|
-
|
|
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) {
|
|
29557
30594
|
return tool({
|
|
29558
30595
|
description: DESCRIPTION2,
|
|
29559
|
-
args: {
|
|
29560
|
-
|
|
29561
|
-
|
|
29562
|
-
|
|
29563
|
-
|
|
29564
|
-
|
|
29565
|
-
|
|
29566
|
-
throw new Error(`PTY session '${args.id}' not found. Use pty_list to see active sessions.`);
|
|
29567
|
-
}
|
|
29568
|
-
if (session.status !== "running") {
|
|
29569
|
-
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>`;
|
|
29570
30603
|
}
|
|
29571
|
-
const
|
|
29572
|
-
const
|
|
29573
|
-
|
|
29574
|
-
|
|
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("");
|
|
29575
30613
|
}
|
|
29576
|
-
|
|
29577
|
-
|
|
29578
|
-
return `
|
|
30614
|
+
lines.push(`Total: ${sessions.length} session(s)`);
|
|
30615
|
+
lines.push("</pty_list>");
|
|
30616
|
+
return lines.join(`
|
|
30617
|
+
`);
|
|
29579
30618
|
}
|
|
29580
30619
|
});
|
|
29581
30620
|
}
|
|
@@ -29709,112 +30748,150 @@ function createPtyReadTool(manager) {
|
|
|
29709
30748
|
}
|
|
29710
30749
|
});
|
|
29711
30750
|
}
|
|
29712
|
-
// src/tools/pty/tools/
|
|
29713
|
-
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.
|
|
29714
30753
|
|
|
29715
|
-
|
|
29716
|
-
-
|
|
29717
|
-
-
|
|
29718
|
-
-
|
|
29719
|
-
-
|
|
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
|
|
29720
30759
|
|
|
29721
|
-
|
|
29722
|
-
- \`
|
|
29723
|
-
- \`
|
|
29724
|
-
- \`
|
|
29725
|
-
- \`
|
|
29726
|
-
- \`
|
|
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
|
|
29727
30770
|
- \`pid\`: Process ID
|
|
29728
|
-
- \`
|
|
29729
|
-
- \`createdAt\`: When the session was created
|
|
30771
|
+
- \`status\`: Current status ("running")
|
|
29730
30772
|
|
|
29731
|
-
|
|
29732
|
-
-
|
|
29733
|
-
-
|
|
29734
|
-
-
|
|
29735
|
-
|
|
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) {
|
|
29736
30784
|
return tool({
|
|
29737
30785
|
description: DESCRIPTION4,
|
|
29738
|
-
args: {
|
|
29739
|
-
|
|
29740
|
-
|
|
29741
|
-
|
|
29742
|
-
|
|
29743
|
-
|
|
29744
|
-
|
|
29745
|
-
|
|
29746
|
-
|
|
29747
|
-
|
|
29748
|
-
|
|
29749
|
-
|
|
29750
|
-
|
|
29751
|
-
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
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(`
|
|
29759
30813
|
`);
|
|
30814
|
+
return output;
|
|
29760
30815
|
}
|
|
29761
30816
|
});
|
|
29762
30817
|
}
|
|
29763
|
-
// src/tools/pty/tools/
|
|
29764
|
-
var DESCRIPTION5 = `
|
|
30818
|
+
// src/tools/pty/tools/write.ts
|
|
30819
|
+
var DESCRIPTION5 = `Sends input data to an active PTY session.
|
|
29765
30820
|
|
|
29766
30821
|
Use this tool to:
|
|
29767
|
-
-
|
|
29768
|
-
-
|
|
29769
|
-
-
|
|
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
|
|
29770
30825
|
|
|
29771
30826
|
Usage:
|
|
29772
30827
|
- \`id\`: The PTY session ID (from pty_spawn or pty_list)
|
|
29773
|
-
- \`
|
|
30828
|
+
- \`data\`: The input to send (text, commands, or escape sequences)
|
|
29774
30829
|
|
|
29775
|
-
|
|
29776
|
-
-
|
|
29777
|
-
-
|
|
29778
|
-
-
|
|
29779
|
-
-
|
|
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"
|
|
29780
30840
|
|
|
29781
|
-
|
|
29782
|
-
- Use cleanup=false if you might want to read the output later
|
|
29783
|
-
- Use cleanup=true when you're done with the session entirely
|
|
29784
|
-
- To send Ctrl+C instead of killing, use pty_write with data="\\x03"
|
|
30841
|
+
Returns success or error message.
|
|
29785
30842
|
|
|
29786
30843
|
Examples:
|
|
29787
|
-
-
|
|
29788
|
-
-
|
|
29789
|
-
|
|
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) {
|
|
29790
30873
|
return tool({
|
|
29791
30874
|
description: DESCRIPTION5,
|
|
29792
30875
|
args: {
|
|
29793
30876
|
id: tool.schema.string().describe("The PTY session ID (e.g., pty_a1b2c3d4)"),
|
|
29794
|
-
|
|
30877
|
+
data: tool.schema.string().describe("The input data to send to the PTY")
|
|
29795
30878
|
},
|
|
29796
30879
|
execute: async (args) => {
|
|
29797
30880
|
const session = manager.get(args.id);
|
|
29798
30881
|
if (!session) {
|
|
29799
30882
|
throw new Error(`PTY session '${args.id}' not found. Use pty_list to see active sessions.`);
|
|
29800
30883
|
}
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
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);
|
|
29804
30889
|
if (!success2) {
|
|
29805
|
-
throw new Error(`Failed to
|
|
30890
|
+
throw new Error(`Failed to write to PTY '${args.id}'.`);
|
|
29806
30891
|
}
|
|
29807
|
-
const
|
|
29808
|
-
const
|
|
29809
|
-
return
|
|
29810
|
-
`<pty_killed>`,
|
|
29811
|
-
`${action}: ${args.id}${cleanupNote}`,
|
|
29812
|
-
`Title: ${session.title}`,
|
|
29813
|
-
`Command: ${session.command} ${session.args.join(" ")}`,
|
|
29814
|
-
`Final line count: ${session.lineCount}`,
|
|
29815
|
-
`</pty_killed>`
|
|
29816
|
-
].join(`
|
|
29817
|
-
`);
|
|
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}"`;
|
|
29818
30895
|
}
|
|
29819
30896
|
});
|
|
29820
30897
|
}
|
|
@@ -30003,6 +31080,7 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30003
31080
|
const commentCheckerHook = createCommentCheckerHook(ctx);
|
|
30004
31081
|
const artifactAutoIndexHook = createArtifactAutoIndexHook(ctx);
|
|
30005
31082
|
const fileOpsTrackerHook = createFileOpsTrackerHook(ctx);
|
|
31083
|
+
const fetchTrackerHook = createFetchTrackerHook(ctx);
|
|
30006
31084
|
const fragmentInjectorHook = createFragmentInjectorHook(ctx, userConfig);
|
|
30007
31085
|
if (userConfig?.fragments) {
|
|
30008
31086
|
const knownAgentNames = new Set(Object.keys(agents));
|
|
@@ -30056,7 +31134,11 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30056
31134
|
}
|
|
30057
31135
|
});
|
|
30058
31136
|
const ptyManager = new PTYManager;
|
|
30059
|
-
const
|
|
31137
|
+
const bunPty = await loadBunPty();
|
|
31138
|
+
if (bunPty) {
|
|
31139
|
+
ptyManager.init(bunPty.spawn);
|
|
31140
|
+
}
|
|
31141
|
+
const ptyTools = ptyManager.available ? createPtyTools(ptyManager) : {};
|
|
30060
31142
|
const spawn_agent = createSpawnAgentTool(ctx);
|
|
30061
31143
|
const batch_read = createBatchReadTool(ctx);
|
|
30062
31144
|
const octtoSessionStore = createSessionStore();
|
|
@@ -30097,7 +31179,6 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30097
31179
|
edit: "allow",
|
|
30098
31180
|
bash: "allow",
|
|
30099
31181
|
webfetch: "allow",
|
|
30100
|
-
doom_loop: "allow",
|
|
30101
31182
|
external_directory: "allow"
|
|
30102
31183
|
};
|
|
30103
31184
|
const mergedAgents = mergeAgentConfigs(agents, userConfig);
|
|
@@ -30153,7 +31234,7 @@ var OpenCodeConfigPlugin = async (ctx) => {
|
|
|
30153
31234
|
...output.options,
|
|
30154
31235
|
thinking: {
|
|
30155
31236
|
type: "enabled",
|
|
30156
|
-
|
|
31237
|
+
budgetTokens: 128000
|
|
30157
31238
|
}
|
|
30158
31239
|
};
|
|
30159
31240
|
}
|
|
@@ -30214,6 +31295,7 @@ IMPORTANT:
|
|
|
30214
31295
|
await contextInjectorHook["tool.execute.after"]({ tool: input.tool, args: input.args }, output);
|
|
30215
31296
|
await artifactAutoIndexHook["tool.execute.after"]({ tool: input.tool, args: input.args }, output);
|
|
30216
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);
|
|
30217
31299
|
await constraintReviewerHook["tool.execute.after"]({ tool: input.tool, sessionID: input.sessionID, args: input.args }, output);
|
|
30218
31300
|
},
|
|
30219
31301
|
"experimental.chat.messages.transform": async (input, output) => {
|
|
@@ -30247,6 +31329,7 @@ IMPORTANT:
|
|
|
30247
31329
|
thinkModeState.delete(sessionId);
|
|
30248
31330
|
ptyManager.cleanupBySession(sessionId);
|
|
30249
31331
|
constraintReviewerHook.cleanupSession(sessionId);
|
|
31332
|
+
fetchTrackerHook.cleanupSession(sessionId);
|
|
30250
31333
|
const octtoSessions = octtoSessionsMap.get(sessionId);
|
|
30251
31334
|
if (octtoSessions) {
|
|
30252
31335
|
for (const octtoSessionId of octtoSessions) {
|
|
@@ -30261,6 +31344,7 @@ IMPORTANT:
|
|
|
30261
31344
|
await tokenAwareTruncationHook.event({ event });
|
|
30262
31345
|
await contextWindowMonitorHook.event({ event });
|
|
30263
31346
|
await fileOpsTrackerHook.event({ event });
|
|
31347
|
+
await fetchTrackerHook.event({ event });
|
|
30264
31348
|
}
|
|
30265
31349
|
};
|
|
30266
31350
|
};
|